Knock out 1/1/0001 Dates in MVC

Back when I coded in Visual Studio 2003, we used to joke that if you wrote a small app that had 100 lines of code, 98 of them would be checking for nulls. It actually wasn’t that far off.

Because of that, I often force my DTO’s to default to DateTime.MinValue instead of nulls and have my code look for MinValue rather than checking for nulls all the time. This has one side effect that I didn’t like, when you use your model in an MVC view, it will display in the text box like “01/01/0001 00:00:00” etc. This is obviously not desirable.

The secondary issue is that when you use Date/Time pickers in the view, they don’t like being bound to DateTime properties, they work better on a string based text box. So what I’ve done is resolve both issues with one solution.

First part is in the ViewModel. I often just inherit my DTO and add or override properties with Attributes/Decorations that I need for the View. I’ll use my ProjectViewModel as an example:

    public class ProjectViewModel : Project
    {
        /// <summary>
        /// Gets or sets the Project Start Date Display
        /// Use to get rid of 01/01/0001 displays
        /// </summary>
        [Display(Name = "Start Date: ")]
        public string StartDateDisplay
        {
            get
            {
                return StartDate.ToShortDateDisplay();
            }
            set
            {
                StartDate = value.ToDateFromString();
            }
        }
    }

In this case, my Project DTO has a StartDate property that is a DateTime. It could be null, or it could be DateTime.MinValue, or it could be a real date. In this implementation, I don’t care about the time, but you could build this out to include time very easily.

When I use this in a view, I use the StartDateDisplay property, rather than the StartDate property.

@Html.TextBoxFor(model => model.StartDateDisplay, new { @class = "form-control", @id = "txtStartDate", @title = "Project Start Date", @type = "text", autocomplete = "off" })

Now this will play nice with the Date/Time picker because it is a string property.

In order to get the dates formated, you’ll notice the ToShortDateDisplay() and the ToDateFromString() extension methods. Those are defined as:

        /// <summary>
        /// Convert a date to a short date string, empty if min or max value
        /// Yasgar Technology Group, Inc. - www.ytgi.com
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToShortDateDisplay(this DateTime value)
        {
            if (value == null) { return string.Empty; }

            if ((value == DateTime.MaxValue) || (value == DateTime.MinValue))
            {
                return string.Empty;
            }
            else
            {
                return value.ToShortDateString();
            }
        }

        /// <summary>
        /// Convert a string in MM/DD/CCYY format to a valid date
        /// Yasgar Technology Group, Inc. - www.ytgi.com
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime ToDateFromString(this string value)
        {
            if (!string.IsNullOrWhiteSpace(value))
            {
                if ((value == "99999999") || (value == "99/99/9999"))
                {
                    return DateTime.MaxValue;
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        DateTime _value;
                        DateTime.TryParse(value, out _value);
                        return _value;
                    }
                    else
                    {
                        return DateTime.MinValue;
                    }
                }
            }

            return DateTime.MinValue;

        }

Solved two issues with one solution. No checking for nulls, no checking for DateTime.MinValue.

Author: Jack Yasgar

Jack Yasgar has been developing software for various industries for two decades. Currently, he utilizes C#, JQuery, JavaScript, SQL Server with stored procedures and/or Entity Framework to produce MVC responsive web sites that converse to a service layer utilizing RESTful API in Web API 2.0 or Microsoft WCF web services. The infrastructure can be internal, shared or reside in Azure. Jack has designed dozens of relational databases that use the proper primary keys and foreign keys to allow for data integrity moving forward. While working in a Scrum/Agile environment, he is a firm believer that quality software comes from quality planning. Without getting caught up in analysis paralysis, it is still possible to achieve a level of design that allows an agile team to move forward quickly while keeping re-work to a minimum. Jack believes, “The key to long term software success is adhering to the SOLID design principles. Software written quickly, using wizards and other methods can impress the business sponsor / product owner for a short period of time. Once the honeymoon is over, the product owner will stay enamored when the team can implement changes quickly and fix bugs in minutes, not hours or days.” Jack has become certified by the Object Management Group as OCUP II (OMG Certified UML Professional) in addition to his certification as a Microsoft Certified Professional. The use of the Unified Modeling Language (UML) provides a visual guide to Use Cases and Activities that can guide the product owner in designing software that meets the end user needs. The software development teams then use the same drawings to create their Unit Tests to make sure that the software meets all those needs. The QA testing team can use the UML drawings as a guide to produce test cases. Once the software is in production, the UML drawings become a reference for business users and support staff to know what decisions are happening behind the scenes to guide their support efforts.

Leave a Reply

Your email address will not be published. Required fields are marked *