DateTime Extensions to Make Some Simple Tasks a Little More Readable






4.92/5 (19 votes)
Sometimes, you want to insert a date into a database as the start of the day, or you need to work out when the last Tuesday of the month is. These aren't difficult tasks, but the code can be difficult to follow. These extensions provide an easy-to-read way to do it.
Introduction
If you want to insert the start of today into a database, you need to pass today's date, at midnight. That isn't difficult, but the code looks clumsy, and needs to be commented:
using (SqlCommand cmd = new SqlCommand("INSERT INTO myTable VALUES (@DATE)", con))
{
DateTime now = DateTime.Now;
cmd.Parameters.AddWithValue("@DATE", new DateTime(now.Year, now.Month, now.Day));
cmd.ExecuteNonQuery();
}
It would be much easier to read if you could just say:
using (SqlCommand cmd = new SqlCommand("INSERT INTO myTable VALUES (@DATE)", con))
{
cmd.Parameters.AddWithValue("@DATE", DateTime.Now.AtMidnight());
cmd.ExecuteNonQuery();
}
In addition, there are times when you want to know the date next Tuesday, or the first Monday of a particular month. This tip presents a small number of extension methods to do just that.
Using the Code
Add a new class file to your project, and copy the code below into it.
You can then use the extension methods as normal:
DateTime pickedDate = dateTimePicker1.Value;
Console.WriteLine("Start date : {0}", pickedDate);
Console.WriteLine("First of month : {0}", pickedDate.FirstOfMonth());
Console.WriteLine("First Tuesday of month : {0}", pickedDate.FirstOfMonth(DayOfWeek.Tuesday));
Console.WriteLine("Last of month : {0}", pickedDate.LastOfMonth());
Console.WriteLine("Last Tuesday of month : {0}", pickedDate.LastOfMonth(DayOfWeek.Tuesday));
Console.WriteLine("Next Tuesday : {0}", pickedDate.NextDayOfWeek(DayOfWeek.Tuesday));
Console.WriteLine("Start of day : {0}", pickedDate.AtMidnight());
Console.WriteLine("Midday : {0}", pickedDate.AtMidday());
The Method Code
using System;
namespace FieldFilterTest
{
/// <summary>
/// Extension methods for DateTime
/// </summary>
public static class DateTimeExtensions
{
#region Public Methods
/// <summary>
/// Returns the first day of the month
/// </summary>
/// <example>
/// DateTime firstOfThisMonth = DateTime.Now.FirstOfMonth;
/// </example>
/// <param name="dt">Start date</param>
/// <returns></returns>
public static DateTime FirstOfMonth(this DateTime dt)
{
return (dt.AddDays(1 - dt.Day)).AtMidnight();
}
/// <summary>
/// Returns the first specified day of the week in the current month
/// </summary>
/// <example>
/// DateTime firstTuesday = DateTime.Now.FirstDayOfMonth(DayOfWeek.Tuesday);
/// </example>
/// <param name="dt">Start date</param>
/// <param name="dayOfWeek">The required day of week</param>
/// <returns></returns>
public static DateTime FirstOfMonth(this DateTime dt, DayOfWeek dayOfWeek)
{
DateTime firstDayOfMonth = dt.FirstOfMonth();
return (firstDayOfMonth.DayOfWeek == dayOfWeek ? firstDayOfMonth :
firstDayOfMonth.NextDayOfWeek(dayOfWeek)).AtMidnight();
}
/// <summary>
/// Returns the last day in the current month
/// </summary>
/// <example>
/// DateTime endOfMonth = DateTime.Now.LastDayOfMonth();
/// </example>
/// <param name="dt" />Start date
/// <returns />
public static DateTime LastOfMonth(this DateTime dt)
{
int daysInMonth = DateTime.DaysInMonth(dt.Year, dt.Month);
return dt.FirstOfMonth().AddDays(daysInMonth - 1).AtMidnight();
}
/// <summary>
/// Returns the last specified day of the week in the current month
/// </summary>
/// <example>
/// DateTime finalTuesday = DateTime.Now.LastDayOfMonth(DayOfWeek.Tuesday);
/// </example>
/// <param name="dt" />Start date
/// <param name="dayOfWeek" />The required day of week
/// <returns />
public static DateTime LastOfMonth(this DateTime dt, DayOfWeek dayOfWeek)
{
DateTime lastDayOfMonth = dt.LastOfMonth();
return lastDayOfMonth.AddDays(lastDayOfMonth.DayOfWeek < dayOfWeek ?
dayOfWeek - lastDayOfMonth.DayOfWeek - 7 :
dayOfWeek - lastDayOfMonth.DayOfWeek) ;
}
/// <summary>
/// Returns the next date which falls on the given day of the week
/// </summary>
/// <example>
/// DateTime nextTuesday = DateTime.Now.NextDayOfWeek(DayOfWeek.Tuesday);
/// </example>
/// <param name="dt">Start date</param>
/// <param name="dayOfWeek">The required day of week</param>
public static DateTime NextDayOfWeek(this DateTime dt, DayOfWeek dayOfWeek)
{
int offsetDays = dayOfWeek - dt.DayOfWeek;
return dt.AddDays(offsetDays > 0 ? offsetDays : offsetDays + 7).AtMidnight();
}
/// <summary>
/// Returns the same day, at midnight
/// </summary>
/// <example>
/// DateTime startOfDay = DateTime.Now.AtMidnight();
/// </example>
/// <param name="dt">Start date</param>
public static DateTime AtMidnight(this DateTime dt)
{
return new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0);
}
/// <summary>
/// Returns the same day, at midday
/// </summary>
/// <example>
/// DateTime startOfAfternoon = DateTime.Now.AtMidday();
/// </example>
/// <param name="dt">Start date</param>
public static DateTime AtMidday(this DateTime dt)
{
return new DateTime(dt.Year, dt.Month, dt.Day, 12, 0, 0);
}
#endregion
}
}
History
- V1.1 Added missing
LastOfMonth
method. Still not sure where it went... - V1.2 6th June 2012
LastOfMonth
fixed: was giving incorrect result when the soughtdayOfWeek
enumeration value is more than thelastDayOfMonth.DayOfWeek
enumeration value. Bug found and suggested fix by VJ Reddy[^] - My thanks to him, and my apologies for any inconvenience caused.