Click here to Skip to main content
15,881,812 members
Articles / Programming Languages / C#

DateTime Extensions to Make Some Simple Tasks a Little More Readable

Rate me:
Please Sign up or sign in to vote.
4.92/5 (20 votes)
6 Jun 2012CPOL 36.3K   19   12
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:

C#
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:

C#
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:

C#
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

C#
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 sought dayOfWeek enumeration value is more than the lastDayOfMonth.DayOfWeek enumeration value. Bug found and suggested fix by VJ Reddy[^] - My thanks to him, and my apologies for any inconvenience caused.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO
Wales Wales
Born at an early age, he grew older. At the same time, his hair grew longer, and was tied up behind his head.
Has problems spelling the word "the".
Invented the portable cat-flap.
Currently, has not died yet. Or has he?

Comments and Discussions

 
GeneralAll hail the Griffin!! Pin
Espen Harlinn6-Jun-12 8:55
professionalEspen Harlinn6-Jun-12 8:55 
GeneralRe: All hail the Griffin!! Pin
OriginalGriff6-Jun-12 9:12
mveOriginalGriff6-Jun-12 9:12 
GeneralRe: All hail the Griffin!! Pin
Espen Harlinn6-Jun-12 9:19
professionalEspen Harlinn6-Jun-12 9:19 
GeneralRe: All hail the Griffin!! Pin
OriginalGriff6-Jun-12 9:30
mveOriginalGriff6-Jun-12 9:30 
GeneralRe: All hail the Griffin!! Pin
Espen Harlinn6-Jun-12 9:37
professionalEspen Harlinn6-Jun-12 9:37 
QuestionDateTime.Today Pin
canozurdo29-May-12 10:59
canozurdo29-May-12 10:59 
QuestionCompile problem Pin
AhsanS11-Mar-12 21:23
AhsanS11-Mar-12 21:23 
AnswerRe: Compile problem Pin
OriginalGriff29-May-12 6:44
mveOriginalGriff29-May-12 6:44 
QuestionSee also Pin
PIEBALDconsult9-Mar-12 9:11
mvePIEBALDconsult9-Mar-12 9:11 
AnswerRe: See also Pin
OriginalGriff9-Mar-12 9:37
mveOriginalGriff9-Mar-12 9:37 
AnswerRe: See also Pin
Robert S Sharp31-May-12 6:44
Robert S Sharp31-May-12 6:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.