C# Tips n Tricks: Get Decimal Places

I needed a quick way to get the number of decimal places on a Double value.  I am displaying the values differently if they have more than 2 decimal values.  Here is a quick helper that I threw together.

public static int GetDecimalCount(this double value)
{
    var str = value.ToStringOrEmpty();
    if (!str.Contains("."))
        return 0;
    return str.Substring(str.IndexOf(".") + 1).Length;
}

C# Tips n Tricks: Simple IsHoliday Class

Today I had a need to check if the current date was a holiday. I wrote up this quick class to do the calculations. This may be a good class to add as an extension to the DateTime class as well. It is one of those nice simple classes that is always useful.

    public class Holiday
    {
        public static bool IsHoliday(DateTime date)
        {
            return
                Holiday.IsNewYearsDay(date)
             || Holiday.IsNewYearsEve(date)
             || Holiday.IsThanksgivingDay(date)
             || Holiday.IsDayAfterThanksgiving(date)
             || Holiday.IsChristmasEve(date)
             || Holiday.IsChristmasDay(date)
             || Holiday.IsFourthOfJuly(date)
             || Holiday.IsLaborDay(date)
             || Holiday.IsMemorialDay(date);
        }
        public static bool IsNewYearsDay(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 1, 1)).DayOfYear;
        }
        public static bool IsNewYearsEve(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 31)).DayOfYear;
        }
        public static bool IsChristmasEve(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 24)).DayOfYear;
        }
        public static bool IsChristmasDay(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 25)).DayOfYear;
        }
        public static bool IsFourthOfJuly(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 7, 4)).DayOfYear;
        }
        public static bool IsLaborDay(DateTime date)
        { // First Monday in September
            DateTime laborDay = new DateTime(date.Year, 9, 1);
            DayOfWeek dayOfWeek = laborDay.DayOfWeek;
            while (dayOfWeek != DayOfWeek.Monday)
            {
                laborDay = laborDay.AddDays(1);
                dayOfWeek = laborDay.DayOfWeek;
            }
            return date.DayOfYear == laborDay.DayOfYear;
        }
        public static bool IsMemorialDay(DateTime date)
        { //Last Monday in May
            DateTime memorialDay = new DateTime(date.Year, 5, 31);
            DayOfWeek dayOfWeek = memorialDay.DayOfWeek;
            while (dayOfWeek != DayOfWeek.Monday)
            {
                memorialDay = memorialDay.AddDays(-1);
                dayOfWeek = memorialDay.DayOfWeek;
            }
            return date.DayOfYear == memorialDay.DayOfYear;
        }
        public static bool IsThanksgivingDay(DateTime date)
        {//4th Thursday in November
            var thanksgiving = (from day in Enumerable.Range(1, 30)
                                where new DateTime(date.Year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                select day).ElementAt(3);
            DateTime thanksgivingDay = new DateTime(date.Year, 11, thanksgiving);
            return date.DayOfYear == thanksgivingDay.DayOfYear;
        }
        public static bool IsDayAfterThanksgiving(DateTime date)
        {//Day after Thanksgiving
            var thanksgiving = (from day in Enumerable.Range(1, 30)
                                where new DateTime(date.Year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                select day).ElementAt(3);
            DateTime thanksgivingDay = new DateTime(date.Year, 11, thanksgiving + 1);
            return date.DayOfYear == thanksgivingDay.DayOfYear;
        }

        private static DateTime AdjustForWeekendHoliday(DateTime holiday)
        {
            if (holiday.DayOfWeek == DayOfWeek.Saturday)
            {
                return holiday.AddDays(-1);
            }
            else if (holiday.DayOfWeek == DayOfWeek.Sunday)
            {
                return holiday.AddDays(1);
            }
            else
            {
                return holiday;
            }
        }
    }

C# Tips n Tricks: ToStringOrEmpty()

Here is another one of those extension methods that I carry with me from job to job.  It’s a super simple one that just makes sense.  So many times I am working with variables that need to be displayed as empty strings when they are null.  The following code gets tiresome when generating dozens of strings in a row.

var displayString = value == null ? String.Empty : value.ToString();

Instead I added the following extension method for strings. Technically it works for any object that has ToString() implemented.

It means that I can simply show the following code which is much simpler and nicer and cleans my code up tremendously.

        public static string ToStringOrEmpty(this object value)
        {
            return ((object)value ?? String.Empty).ToString();
        }

Update: A former co-worker sent me this CodeProject Article: Chained null checks and the Maybe monad that takes this concept a bit further with a fairly complex set of extensions that allow cleaning up null checks even more.  I’ll have to dig into it deeper.

C# Tips n Tricks: Adding a "From Camel Case" string extension method

On occasion I am working with strings that are simply the enum value, such as “MyEnum.SampleEnumName”.  I want to display it as a string without the camelcase formatting “Sample Enum Name”.  To do this I added the following FromCamelCase extension method to string.

namespace CustomExtensions
{
    public static class StringExtension
    {
        public static string ToStringOrEmpty(this object value)
        {
            return string.Concat(value, "");
        }

        /// <summary>
        /// Converts a string from CamelCase to a human readable format. 
        /// Inserts spaces between upper and lower case letters. 
        /// Also strips the leading "_" character, if it exists.
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns>A human readable string.</returns>
        public static string FromCamelCase(this string propertyName)
        {
            string returnValue = null;
            returnValue = propertyName.ToStringOrEmpty();

            //Strip leading "_" character
            returnValue = Regex.Replace(returnValue, "^_", "").Trim(); 
            //Add a space between each lower case character and upper case character
            returnValue = Regex.Replace(returnValue, "([a-z])([A-Z])", "$1 $2").Trim(); 
            //Add a space between 2 upper case characters when the second one is followed by a lower space character
            returnValue = Regex.Replace(returnValue, "([A-Z])([A-Z][a-z])", "$1 $2").Trim(); 

            return returnValue;
        }
    }
}