Get the most recently passed Monday

I need to take a date, and get the most recently passed Monday. So if the date I have falls on a Tuesday, I need to return the previous days date. If it falls on a Friday then I need to get the date 4 days before it. If it is a Monday, the same date is returned.

Sounds simple enough? That’s what I thought, but it has been giving me a real headache!

Originally I came up with:

mydate.AddDays(1 - mydate.DayOfWeek)

And then:

mydate.AddDays(-(mydate.DayOfWeek - DayOfWeek.Monday))

But they both give the same result. It works fine if the input date is a Monday through Saturday, but if the input date is a Sunday then it returns the day (Monday) after, as the following code illustrates:

Dim mydate As DateTime = DateTime.ParseExact("01/01/2011", "dd/MM/yyyy", Nothing)
For i As Integer = 1 To 365
            Response.Write(mydate.ToString("dddd, dd MMMM yyyy") & " : Last Monday was " & mydate.AddDays(-(mydate.DayOfWeek - DayOfWeek.Monday)).ToString("dddd, dd MMMM yyyy") & vbCrLf)
            mydate = mydate.AddDays(1)
Next

Output:

Saturday, 01 January 2011 : Last Monday was Monday, 27 December 2010
Sunday, 02 January 2011 : Last Monday was Monday, 03 January 2011
Monday, 03 January 2011 : Last Monday was Monday, 03 January 2011
Tuesday, 04 January 2011 : Last Monday was Monday, 03 January 2011
Wednesday, 05 January 2011 : Last Monday was Monday, 03 January 2011
Thursday, 06 January 2011 : Last Monday was Monday, 03 January 2011
Friday, 07 January 2011 : Last Monday was Monday, 03 January 2011
Saturday, 08 January 2011 : Last Monday was Monday, 03 January 2011
Sunday, 09 January 2011 : Last Monday was Monday, 10 January 2011
Monday, 10 January 2011 : Last Monday was Monday, 10 January 2011
Tuesday, 11 January 2011 : Last Monday was Monday, 10 January 2011
Wednesday, 12 January 2011 : Last Monday was Monday, 10 January 2011
Thursday, 13 January 2011 : Last Monday was Monday, 10 January 2011
Friday, 14 January 2011 : Last Monday was Monday, 10 January 2011
Saturday, 15 January 2011 : Last Monday was Monday, 10 January 2011
Sunday, 16 January 2011 : Last Monday was Monday, 17 January 2011
Monday, 17 January 2011 : Last Monday was Monday, 17 January 2011
Tuesday, 18 January 2011 : Last Monday was Monday, 17 January 2011
Wednesday, 19 January 2011 : Last Monday was Monday, 17 January 2011
Thursday, 20 January 2011 : Last Monday was Monday, 17 January 2011
Friday, 21 January 2011 : Last Monday was Monday, 17 January 2011
Saturday, 22 January 2011 : Last Monday was Monday, 17 January 2011
Sunday, 23 January 2011 : Last Monday was Monday, 24 January 2011
Monday, 24 January 2011 : Last Monday was Monday, 24 January 2011
Tuesday, 25 January 2011 : Last Monday was Monday, 24 January 2011
Wednesday, 26 January 2011 : Last Monday was Monday, 24 January 2011
Thursday, 27 January 2011 : Last Monday was Monday, 24 January 2011
Friday, 28 January 2011 : Last Monday was Monday, 24 January 2011
Saturday, 29 January 2011 : Last Monday was Monday, 24 January 2011
Sunday, 30 January 2011 : Last Monday was Monday, 31 January 2011
Monday, 31 January 2011 : Last Monday was Monday, 31 January 2011
Tuesday, 01 February 2011 : Last Monday was Monday, 31 January 2011
Wednesday, 02 February 2011 : Last Monday was Monday, 31 January 2011
Thursday, 03 February 2011 : Last Monday was Monday, 31 January 2011
Friday, 04 February 2011 : Last Monday was Monday, 31 January 2011
Saturday, 05 February 2011 : Last Monday was Monday, 31 January 2011
Sunday, 06 February 2011 : Last Monday was Monday, 07 February 2011
...
etc.

Can anyone shed some light on this for me? I’m surprised how little I have found when searching online.

Thanks in advance.

I thought I should add that I am aware I could do this by counting backwards in a loop - I just thought there must be a simple way to do it mathematically.

That sounds both simple and mathematical. Test. -1. Repeat.

But they both give the same result. It works fine if the input date is a Monday through Saturday, but if the input date is a Sunday then it returns the day (Monday) after,

I know nothing about .NET, but it sounds like DayofWeek returns 0 for sunday (for some reason some regard sunday as the first day of the week instead of the last).

I don’t know if there’s a way that you can make the date functions regard sunday as the last day of the week (7) ?

Here is what I’d use:

 public static DateTime GetLastMonday(DateTime before)
        {
            var dayMathMap = new Dictionary<DayOfWeek, int>()
                                                        {
                                                            {DayOfWeek.Sunday, -6},
                                                            {DayOfWeek.Monday, 0},
                                                            {DayOfWeek.Tuesday, -1},
                                                            {DayOfWeek.Wednesday, -2},
                                                            {DayOfWeek.Thursday, -3},
                                                            {DayOfWeek.Friday, -4},
                                                            {DayOfWeek.Saturday, -5},
                                                        };
            return before.AddDays(dayMathMap[before.DayOfWeek]);
        }

Thank you for you comments, I think I’ll go with the dictionary.