Friday, March 28, 2008

Original Post:
http://www.iridescence.no/Posts/A-Set-of-Useful-Extension-Methods-for-DateTime.aspx

I was just reading Rich Strahl's post today on formatting dates in JavaScript, in which he mentions that the .NET framework has a fairly rich API for working with dates. Compared to JavaScript, he's definitively right - but that doesn't mean that the DateTime API is anything near perfect. Disregarding all the minute detail problems regarding time zones and such, or the fact that we're forced to deal with date AND time together and no separating the two, there are some things that are just plain cumbersome and tedious to get done with it. But lo and behold, with the new extensions method feature in C# 3.0 we can do something about that - so in this post I'd like to present 11 time-saving (oh, the pun!) extensions for the DateTime class.

The Extentions

First()This method returns a DateTime representing the first day of the month represented by the instance it is called on. For example:

DateTime firstOfMarch = DateTime.Now.First();

First(DayOfWeek dayOfWeek)

This method returns the first occurrence of the specified day in the month represented by the instance it is called on. For example, the first Monday of this month was the 3rd of March:

DateTime thirdOfMarch = DateTime.Now.First(DayOfWeek.Monday);
Last()

This method returns a DateTime representing the last day of the month represented by the instance it is called on. For example:

DateTime lastDayOfMarch = DateTime.Now.Last();
Last(DayOfWeek dayOfWeek)

This method returns a DateTime representing the last occurence of the specified day in the month represented by the instance it is called on. For example, the last Tuesday of this month will be the 25th of March:

DateTime lastTuesdayOfMarch = DateTime.Now.Last(DayOfWeek.Tuesday);

Midnight()

This method returns a DateTime representing midnight on the day represented by the instance it is called on:

DateTime midnightToday = DateTime.Now.Midnight();
Noon()This method returns a DateTime representing noon on the day represented by the instance it is called on:
DateTime noonToday = DateTime.Now.Noon();

Next(DayOfWeek dayOfWeek)

This method returns the first date falling on the specified day following the one represented by the instance it is called on. For example, to get a DateTime representing next monday:

DateTime nextMonday = DateTime.Now.Next(DayOfWeek.Monday);
SetTime(hour)
SetTime(hour, minute)
SetTime(hour, minute, second)
SetTime(hour, minute, second, millisecond)

These four overloads can be used to get a DateTime representing a different time of day on the same date as the instance it is called on.

For instance, if we want to get a DateTime representing 11am today:
DateTime lunchTime = DateTime.Now.SetTime(11);

Almost Fluent
Since each of these methods in turn return a new DateTime instance, they can be chained together in a way resembling fluent interfaces. For example, say I wanted to represent half past two PM, next Tuesday:

DateTime lateLunchWithCustomer = DateTime.Now.Next(DayOfWeek.Tuesday).SetTime(14,30);

Or maybe I want to represent midnight on the second Monday of the month:
DateTime secondMondayOfMonth = DateTime.Now.First(DayOfWeek.Monday).Next(DayOfWeek.Monday).Midnight();

Go Get It!

I've created a project and uploaded the source code for the extension methods and accompanying unit tests to Codeplex - as much for having an excuse to test Codeplex, as for the fact that the methods I've knocked together this evening could just be the beginnings of a larger and more useful set of extensions for the DateTime class.

No comments: