23

I'm ordering a number of objects by their System.DayOfWeek property.

DayOfWeek treats Sunday as the start of the week, whereas I would like it to be ordered so it appears at the end. It's just an enum, so I can't modify it. However I've read that I may be able to create a custom culture but think this is probably overkill.

List<TimeBand> orderedTimeBands = timeBands.OrderBy(x => x.DayName).ToList()

So DayName is a DayOfWeek, i want orderedTimeBands to be ordered from Monday -> Sunday.

Any ideas?

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
m.edmondson
  • 30,382
  • 27
  • 123
  • 206

2 Answers2

54

The simplest approach would be:

var orderedTimeBands = timeBands.OrderBy(x => ((int) x.DayOfWeek + 6) % 7)
                                .ToList()

So we have:

Name        Original value      Value after arithmetic
Sunday       0                  6
Monday       1                  0
Tuesday      2                  1
Wednesday    3                  2
Thursday     4                  3
Friday       5                  4
Saturday     6                  5

... which is what you want, I think.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • this ( +1 ) or as pointed out in http://stackoverflow.com/questions/3135587/c-set-initial-dayofweek-as-monday-not-sunday you could write a "custom" CurrentCulture and simply tell there that its monday – Najzero Sep 03 '13 at 11:27
  • @Najzero: Yes, the OP mentioned the custom culture idea in the question. I'd definitely consider that to be overkill. – Jon Skeet Sep 03 '13 at 11:27
  • Great example of thinking out of the box, glad you agree with me that a custom culture is overkill. Seems to work, I'll just make sure I put it in a method that describes why we're using addition and modulus to save future confusion. – m.edmondson Sep 03 '13 at 11:35
14

I use a solution based on current culture:

// all days of week
var daysOfWeek = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>();

// get first day of week from current culture
var firstDayOfWeek = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;

// all days of week ordered from first day of week
var daysOfWeekOrdered = daysOfWeek.OrderBy(x => (x - firstDayOfWeek + 7) % 7);

The important part is the OrderBy lambda. It's basically a parametrized version of Jon's answer above.

This way it will be ordered from Monday in the UK, and from Sunday in the US.

Community
  • 1
  • 1
Tom Pažourek
  • 9,582
  • 8
  • 66
  • 107