UPDATE: Writing Fluent APIs in C#: Comparing Dates Fluently

by Doug Finke on March 7, 2010

in .Net,C#,Extension Method,Fluent API

I posted a C# version HERE based on Ted Young’s Java version HERE. Then Professor Roger Crawfis commented and we traded emails.

I do not see the point to the DateBuilder class here. Extension methods would be a better approach (IMHO) for all of the methods.

New and Improved version with Extension Methods

   1: using System;

   2: using System.Diagnostics;

   3:  

   4: namespace ConsoleApplication1

   5: {

   6:     class Program

   7:     {

   8:         static void Main(string[] args)

   9:         {

  10:             var earlierDate = new DateTime(2010, 1, 10);

  11:             var laterDate = new DateTime(2010, 1, 31);

  12:  

  13:             Debug.Assert(earlierDate.IsBefore(laterDate));

  14:             Debug.Assert(!laterDate.IsBefore(earlierDate));

  15:  

  16:             Debug.Assert(laterDate.OnOrAfter(earlierDate));

  17:             Debug.Assert(laterDate.OnOrAfter(laterDate));

  18:             Debug.Assert(!earlierDate.OnOrAfter(laterDate));

  19:  

  20:             Debug.Assert(earlierDate.OnOrBefore(laterDate));

  21:             Debug.Assert(earlierDate.OnOrBefore(earlierDate));

  22:             Debug.Assert(!laterDate.OnOrBefore(earlierDate));

  23:  

  24:             Debug.Assert(laterDate.On(laterDate));

  25:             Debug.Assert(!laterDate.On(earlierDate));

  26:         }

  27:     }

  28:  

  29:     public static class DateExtensions

  30:     {

  31:         public static bool IsBefore(this DateTime firstDateTime, DateTime otherDate)

  32:         {

  33:             return (firstDateTime < otherDate) ? true : false;

  34:         }

  35:  

  36:         public static bool IsAfter(this DateTime firstDateTime, DateTime otherDate)

  37:         {

  38:             return (firstDateTime > otherDate) ? true : false;

  39:         }

  40:  

  41:         public static bool OnOrAfter(this DateTime firstDateTime, DateTime otherDate)

  42:         {

  43:             return (firstDateTime >= otherDate) ? true : false;

  44:         }

  45:  

  46:         public static bool OnOrBefore(this DateTime firstDateTime, DateTime otherDate)

  47:         {

  48:             return (firstDateTime <= otherDate) ? true : false;

  49:         }

  50:  

  51:         public static bool On(this DateTime firstDateTime, DateTime otherDate)

  52:         {

  53:             return firstDateTime.Equals(otherDate);

  54:         }

  55:     }

  56: }

{ 7 comments… read them below or add one }

Paul Cassidy 03.07.10 at 11:50 pm

How does the compiler know to bind these to the Datetime object? does not the method need some reference to the Type to bind On.

Doug Finke 03.09.10 at 9:48 pm

Paul, these are extension methods.

Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier.

http://msdn.microsoft.com/en-us/library/bb383977.aspx

John Putman 03.09.10 at 11:45 pm

This may seem a bit pedantic, but is there a reason that you are using the conditional operator (?:) here, like:

return (firstDateTime <= otherDate) ? true : false;

instead of simply returning the result of the expression:

return (firstDateTime <= otherDate);

It just seems like this is excess code, unless you do this for readability or something…

Doug Finke 03.10.10 at 7:05 pm

Thanks John, good catch. I had re-worked this code which I had modeled after some other Java code.

No need for it! Less is more.

Aaron Goldman 03.10.10 at 7:18 pm

I think date1 < date2 is rather expressive in itself, but this method might be good for cases where time needs to be stripped and the date part is important:

date1.IsSameDayAs(date2) might be helpful

I'm also a a stickler for comparisons returning bool without extra help, but it seem John Putnam beat me to that comment.

Doug Finke 03.13.10 at 3:40 pm

Thanks Aaron, good point.

Sly Gryphon 03.16.10 at 6:46 am

Although I question the wisdom of writing methods simply to replace “d1 <= d2" with "d1.OnOrBefore(d2)" (i.e. is being "Fluent" really that useful), if you are going to do date manipulations then you should at least be using DateTimeOffset (in preference to DateTime).

From the MSDN documentation "DateTimeOffset should be considered the default date and time type for application development." (http://msdn.microsoft.com/en-us/library/bb384267.aspx)

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>