Recently I wrote a page that contained a Dropdown list of dates. I decided that the dates that I wanted to display should be formatted with an ordinal part to the date, i.e.
Thursday 28th March 2013
because this is more friendly than, say,
Thursday 28 March 2013.
Unfortunately, the standard DateTime formatting options do not offer this. The solution was to add an extension method to the Datetime class to offer the additional formatting:
public static class DateHelper { public static string FullDateOrdinalDayFormat (this DateTime datetime) { string daystring; switch (datetime.Day % 10) { case 1: daystring = "st"; break; case 2: daystring = "nd"; break; case 3: daystring = "rd"; break; default: daystring = "th"; break; } return string.Format("{0} {1}{2} {3}", datetime.DayOfWeek, datetime.Day.ToString("d"), daystring, datetime.ToString(" MMMM yyyy")); } }
So far, so good.
This extension method offered the correct string for the dropdown list, but unfortunately could not be parsed directly by the DateTime class to get a valid date. The solution, then, was to use the formatted string as the dropdown list visible text, with a DateTime-parsable string as the value. Using the DataTextField and DataValueField, solved this:
<asp:DropDownList ID="FirstDepartureDateDropdownList" runat="server"
DataTextField="Value" DataValueField="Key"/>
with the code behind populating the dropdown list using a list of KeyValuePair:
FirstDepartureDateDropdownList.DataSource = (from departureData in pricesData where departureData.StartDate > DateTime.Now.Date select new KeyValuePair<DateTime, string>(departureData.StartDate, departureData.StartDate.FullDateOrdinalDayFormat())).ToList(); FirstDepartureDateDropdownList.DataBind();
This renders the select HTML as:
<option value="28/03/2013 00:00:00" selected="selected"> Thursday 28th March 2013</option>
Which can be parsed back into a DateTime for further processing, thus:
private static DateTime GetDepartureDateFromString(string date) { DateTime dt; return DateTime.TryParse(date, out dt) ? dt : DateTime.MinValue; }
So, users get a better experience, and the dates are stored correctly as dates. Clearly this solution could be extended for date strings in different languages, but English strings were all I needed. YAGNI.