Reader challenge!

It’s been a while since we’ve had a reader question, so here’s one for you all. It’s not that I can’t solve this problem; it’s more that I’m wondering if there’s a more elegant solution.

The Problem: Given two dates, what’s the easiest way of determining if they fall in the same week?

Please submit your answers as a comment!

Posted in C#, Daily Question by Gerrod at November 3rd, 2008.

9 Responses to “Reader challenge!”

  1. Ben says:

    I’ll start with a simple implementation that assumes the week begins on a Sunday.

    
    ///
    
    /// Verify two dates are within the same 7 day week where the week begins on a Sunday.
    /// 
    
    public static bool InSameWeekSimple(this DateTime d1, DateTime d2) {   
    
                if (d2 < d1) { Swap(ref d1, ref d2); } // ensure d1 is less than or equal to d2
                DateTime beginningOfWeekDate2 = d2.AddDays(-(int)d2.DayOfWeek);
                return d1 >= beginningOfWeekDate2 && d1 < = d2; // verify that d1 is greater than the date that begins d2s week and less than d2.
    }
    
    
     private static void Swap(ref T obj1, ref T obj2) {
                var temp = obj1;
                obj1 = obj2;
                obj2 = temp;
    }
    

    This can be extended to work with a week beginning on a different day to Sunday:

    
    public static class ExtensionMethods {
    
      ///
    
      /// Verify two dates are within the same 7 day week where the week begins on a Sunday.
      /// 
    
      public static bool InSameWeek(this DateTime d1, DateTime d2) {
        return InSameWeek(d1, d2, DayOfWeek.Sunday);
      }
    
      ///
    
      /// Verify two dates are within the same 7 day week, specifying which   day begins the week.
      /// 
    
      public static bool InSameWeek(this DateTime d1, DateTime d2, DayOfWeek weekBeginDay) {
        if (d2 < d1) { Swap(ref d1, ref d2); } // ensure d1 is less than or equal to d2
        DateTime beginningOfWeekDate2 = d2.AddDays(-(int)d2.DayOfWeek);
        //DateTime beginningOfWeekDate2 = d2.AddDays(((weekBeginDay - d2.DayOfWeek) - 7)%7);
        return d1 >= beginningOfWeekDate2 && d1 < = d2; // verify that d1 is greater than the date that begins d2s week and less than d2.
      }
    
      ///
    
      /// Verify two dates are within monday-friday of the same week.
      ///
      public static bool InSameWeekdays(this DateTime d1, DateTime d2) {
        if (IsWeekendDay(d1) || IsWeekendDay(d2)) { return false; }
        if (d2 < d1) { Swap(ref d1, ref d2); } // ensure d1 is less than or equal to d2
        return d1 >= d2.AddDays(-((int)d2.DayOfWeek - (int)DayOfWeek.Monday)) && d1 < = d2; // verify that d1 is greater than the date that begins d2s week and less than d2.
      }
    
      ///
    
      /// Does the date provided fall on a Saturday or Sunday
      ///
      public static bool IsWeekendDay(DateTime date) {
        return date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
      }
    
      private static void Swap(ref T obj1, ref T obj2) {
        var tempDate = obj1;
        obj1 = obj2;
        obj2 = tempDate;
      }
    }
    
    

    All of these functions were unit tested and can be verified.

    Do I win?

  2. Try the DateJs library. Its a great library with a heap of tools for all your dating needs.

  3. Andrew says:


    public static bool InSameWeek(DateTime d1, DateTime d2)
    {
    Calendar cal = new GregorianCalendar();
    int weekNo1 = cal.GetWeekOfYear(d1, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
    int weekNo2 = cal.GetWeekOfYear(d2, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
    return weekNo1 == weekNo2;
    }

  4. gerrod says:

    Thanks for the answers guys.

    Ben’s answer was by far the most comprehensive and I’d lean towards that if I was making a DateTime library (which as Drew suggested, probably already exists).

    Andrew’s answer however is much simpler and closer to what I need for this particular purpose.

    Here’s what I came up with – essentially a cut down version of Ben’s. Note that itemDate is the date being tested:

    
    DateTime today = DateTime.Today;
    
    DateTime thisWeekStart = today.AddDays(
        DayOfWeek.Sunday - today.DayOfWeek);
    
    DateTime thisWeekEnd = today.AddDays(
        DayOfWeek.Saturday - today.DayOfWeek);
    
    if (itemDate > thisWeekStart && itemDate.Date <= thisWeekEnd)
        return "This week";
    
  5. Andrew says:

    Yeah! Slow and simple wins the race. No wait, slow and special…. no wait…..

  6. Ben says:

    We should do more of these challenges as I find I always learn something new.

    Thanks Andrew for pointing me towards the GregorianCalendar class.

  7. Paulo Santos says:

    I think Andrew is far from being correct. Dates in different years will result in same week.
    And what happens on cases where the 1st of january is a wednesday and you compare 30/Dec with 2/Jan?

    I have now the same problem, I think I ll take a look at Ben’s solution.

  8. This should work

    public static bool InSameWeek(DateTime d1, DateTime d2)
    {
    DateTime beginningOfWeekDate1 = d2.AddDays(-(int)d2.DayOfWeek);
    DateTime beginningOfWeekDate2 = d2.AddDays(-(int)d2.DayOfWeek);
    return beginningOfWeekDate1 == beginningOfWeekDate2;
    }

    Thanks Ben!

  9. ops, there’s copy paste bug there.

    DateTime beginningOfWeekDate1 = d1.AddDays(-(int)d1.DayOfWeek);

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may 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>

Quickduck logo