user2477207
user2477207

Reputation: 31

How to get date after N months with same day and same week of a given date

I am looking for some logic to get the date after N months having same day(Ex:Wednesday) and same week(ex: first or second...) of a given date.

ex: 12-06-2013(Wednesday & 3rd week of June) is the given date. here I am adding 3 months to the given date. the result should be is 14-Aug-2013(Wednesday & 3rd week of Aug).

please let me know if you need more clarification.

Thanks In advance.

Upvotes: 2

Views: 1436

Answers (2)

hazzelnuttie
hazzelnuttie

Reputation: 1481

Using standard MDSN year = 2013 month = 06 date = 12

1) Get day of the week from the specific date (Sunday is 0)

DateTime dateValue = new DateTime(year, month, date);  
Console.WriteLine((int) dateValue.DayOfWeek);      // Displays 3 implying it is Wed

2) Get the week of the month from the specific date

DayofWeek = 3 (from previous calculation)
Day = 12 
EndOfWeek = Day + (6 - DayOfWeek) = 12 + 4 = 16  
NoWeek = 0
while (EndOfWeek > 0)
{
   EndOfWeek  -= 7;
   NoWeek++;        
}

=> NoWeek = 3

3) Get first date after N month

DateTime newDate = new DateTime(year, month, 1)

newDate.AddMonths(N); // Let it be 2 => August 1, 2013

4) Get the day of the week for the new date

newDay = newDate.DayOfWeek  // Return 4 implying Thursday

5) Get the last day after NoWeek

newDate.AddDays(6-newDay) => newDate.AddDays (6-4) => August 3,2013
NoWeek--;
while (NoWeek > 1)
{
    newDate.AddDays(7);
    NoWeek--;
}

=> newDate will be Augus 10,2013

6) Calculte required date

newDate.AddDays(DayofWeek) =>newDate will be August 14,2013

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502476

Okay, so I'd personally use my Noda Time library to do this. It's entirely possible to do this with DateTime, but I'd personally find it harder. I'd also encourage you to use Noda Time in general, of course, as a better date/time API. So I'd have something like:

static LocalDate AddMonthsPreserveWeekDayAndWeek(LocalDate start, int months)
{
    // This isn't the week of month in the "normal" sense; it's the nth
    // occurrence of this weekday.
    int week = ((start.DayOfMonth - 1) / 7) + 1;

    // This will usually give the same day of month, but truncating where
    // necessary
    LocalDate monthsAdded = start.AddMonths(months);
    LocalDate endOfPreviousMonth = monthsAdded.AddDays(-monthsAdded.Day);

    // Get to the first occurrence of the right day-of-week
    LocalDate firstRightDay = endOfPreviousMonth.Next(start.IsoDayOfWeek);

    // Usually this will be right - but it might overflow to the next month,
    // in which case we can just rewind by a week.
    LocalDate candidate = firstRightDay.PlusWeeks(week - 1);
    return candidate.Month == firstRightDay.Month ? candidate
                                                  : candidate.PlusWeeks(-1);
}

This is completely untested though - you should absolutely have a bunch of unit tests (ideally which you write before even including this code) which test all kinds of edge cases you're interested in.

Upvotes: 3

Related Questions