I recently found myself having a DateTime value and needing to calculate the date of the first day in the week that my known date was in using C#. While this is one of those things that are pretty simple to do once you know the solution it did take me a couple of hours to get it right. It turns out that something as simple as calculating a the first day of a week is trickier than one might expect, at least if we want a solution that works for all cultures.
My first instinct was to calculate the first day of a week by subtracting dayInWeek.DayOfWeek - firstDayInWeek days from dayInWeek where dayInWeek is a DateTime specifying a date in the week. That worked fine as long as I did the calculations in an environment where the culture was English, where the first day of the week is Sunday which is enumerated as 0 in DayOfWeek (against international standards which says the first day of the week is monday). As I shifted to using a Swedish culture it broke down and I had to find a better solution.
Heres what I finally came up with:
using System;
using System.Globalization;
public static class FirstDayOfWeekUtility
{
/// <summary>
/// Returns the first day of the week that the specified
/// date is in using the current culture.
/// </summary>
public static DateTime GetFirstDayOfWeek(DateTime dayInWeek)
{
CultureInfo defaultCultureInfo = CultureInfo.CurrentCulture;
return GetFirstDateOfWeek(dayInWeek, defaultCultureInfo);
}
/// <summary>
/// Returns the first day of the week that the specified date
/// is in.
/// </summary>
public static DateTime GetFirstDayOfWeek(DateTime dayInWeek, CultureInfo cultureInfo)
{
DayOfWeek firstDay = cultureInfo.DateTimeFormat.FirstDayOfWeek;
DateTime firstDayInWeek = dayInWeek.Date;
while (firstDayInWeek.DayOfWeek != firstDay)
firstDayInWeek = firstDayInWeek.AddDays(-1);
return firstDayInWeek;
}
}
PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.
This blog is built with EPiServer Community, EPiServer CMS, ASP.NET MVC and a bunch of other great products. The source code is available for download at the projects page, where you also can read more about this site and my other projects.
read more
Comments
colin 1 years ago
This works... it deals with "less than zero values" by doing the (+7)%7 method. it also lets the programmer decide if he's going to override the culture's first day of week with an evil Business Rule.
******
public static DateTime GetFirstDayInWeek(DateTime dayInWeek, DayOfWeek firstDay) {
int difference = ((int)dayInWeek.DayOfWeek) - ((int)firstDay);
difference = (7 + difference) % 7;
return dayInWeek.AddDays(-difference).Date;
}
******
public static DateTime GetFirstDayInWeek(DateTime dayInWeek) {
return GetFirstDayInWeek(dayInWeek, CultureInfo.CurrentCulture);
}
public static DateTime GetFirstDayInWeek(DateTime dayInWeek, CultureInfo cultureInfo) {
return GetFirstDayInWeek(dayInWeek, cultureInfo.DateTimeFormat.FirstDayOfWeek);
}
Andrea 5 months ago
I think this is better:
DateTime aday = new DateTime(2010,04,09).DayOfWeek;
DateTime firstDate = aday.AddDays(-(int)aday.DayOfWeek);
Joel Abrahamsson 5 months ago
Andrea, the problem with that approach is that it doesn't work for all cultures as DayOfWeek is an enum that says that Sunday is the first day of the week. So while that approach works in cultures where Sunday is the first day of the week it doesn't for cultures where it isn't.