views:

7096

answers:

10

Anyone know an easy way to get the date of the first day in the week (monday here europe). I know the year and the week number? I'm going to do this in C#.

Thanks in advance.

+2  A: 

The easiest way is probably to find the first Monday of the year, and then add the relevant number of weeks. Here's some sample code. It assumes a week number starting at 1, by the way:

using System;

class Test
{
    static void Main()
    {
        // Show the third Tuesday in 2009. Should be January 20th
        Console.WriteLine(YearWeekDayToDateTime(2009, DayOfWeek.Tuesday, 3));
    }

    static DateTime YearWeekDayToDateTime(int year, DayOfWeek day, int week)
    {
        DateTime startOfYear = new DateTime (year, 1, 1);

        // The +7 and %7 stuff is to avoid negative numbers etc.
        int daysToFirstCorrectDay = (((int)day - (int)startOfYear.DayOfWeek) + 7) % 7;

        return startOfYear.AddDays(7 * (week-1) + daysToFirstCorrectDay);
    }
}
Jon Skeet
Yep, but the first monday of the year could belong to week 52|53 of the previous year.
Henk Holterman
It depends how you want to define things. Unfortunately we don't have a lot of information to go on here... I'm hoping this is useful though.
Jon Skeet
+1  A: 

Maybe this will be of some use C# Getting Start Date of Week

Christian Witts
A: 

Week 1 is defined as being the week that starts on a Monday and contains the first Thursday of the year.

amaca
That's one definition, there are others.
Henk Holterman
+14  A: 

The code below is essentially the same calculation as Jon Skeet's, but it correctly puts the start of week 1, 2009 at 29-12-2008. The CalendarWeekRule probably should be a parameter.

Edit: first version got most other years wrong, corrected version below.

Note that the weekNum should be >= 1

static DateTime FirstDateOfWeek(int year, int weekNum, CalendarWeekRule rule)
{
    Debug.Assert(weekNum >= 1);

    DateTime jan1 = new DateTime(year, 1, 1);

    int daysOffset = DayOfWeek.Monday - jan1.DayOfWeek;
    DateTime firstMonday = jan1.AddDays(daysOffset);
    Debug.Assert(firstMonday.DayOfWeek == DayOfWeek.Monday);

    var cal = CultureInfo.CurrentCulture.Calendar;
    int firstWeek = cal.GetWeekOfYear(jan1, rule, DayOfWeek.Monday);

    if (firstWeek <= 1)
    {
        weekNum -= 1;
    }

    DateTime result = firstMonday.AddDays(weekNum * 7);

    return result;
}
Henk Holterman
Thanks, works great. I used "CalendarWeekRule.FirstDay" as the CalendarWeekRule parameter.
aticatac
A: 

Personally I'd take advantage of the culture info to get the day of the week and loop down to the culture's first day of the week. I'm not sure if I'm explaining it properly, here's an example:

    public DateTime GetFirstDayOfWeek(int year, int weekNumber)
    {
        return GetFirstDayOfWeek(year, weekNumber, Application.CurrentCulture);
    }

    public DateTime GetFirstDayOfWeek(int year, int weekNumber,
        System.Globalization.CultureInfo culture)
    {
        System.Globalization.Calendar calendar = culture.Calendar;
        DateTime firstOfYear = new DateTime(year, 1, 1, calendar);
        DateTime targetDay = calendar.AddWeeks(firstOfYear, weekNumber);
        DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;

        while (targetDay.DayOfWeek != firstDayOfWeek)
        {
            targetDay = targetDay.AddDays(-1);
        }

        return targetDay;
    }
Alexander Kahoun
+1  A: 

According to ISO 8601:1988 that is used in Sweden the first week of the year is the first week that has at least four days within the new year.

So if your week starts on a Monday the first Thursday any year is within the first week. You can DateAdd or DateDiff from that.

idstam
+8  A: 

I like the solution provided by Henk Holterman. But to be a little more culture independent, you have to get the first day of the week for the current culture ( it's not always monday ):

using System.Globalization;

static DateTime FirstDateOfWeek(int year, int weekOfYear)
{
  DateTime jan1 = new DateTime(year, 1, 1);

  int daysOffset = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;

  DateTime firstMonday = jan1.AddDays(daysOffset);

  int firstWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(jan1, CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule, CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek);

  if (firstWeek <= 1)
  {
    weekOfYear -= 1;
  }

  return firstMonday.AddDays(weekOfYear * 7);
}
Thomas
this should be the accepted solution
Lemmy
I've added this to Mannex, as an extension method to Calendar and DateTimeFormatInfo. I've also cross-referenced to this answer for credit.
Atif Aziz
It doesn't work properly on my machine. It shows a date with 0010 instead of 2010. I don't know if it is a problem in .net framework or in this function. Nice try, anyway...
Eduardo Xavier
+1  A: 

using Fluent DateTime http://fluentdatetime.codeplex.com/

        var year = 2009;
        var firstDayOfYear = new DateTime(year, 1, 1);
        var firstMonday = firstDayOfYear.Next(DayOfWeek.Monday);
        var weeksDateTime = 12.Weeks().Since(firstMonday);
Simon
A: 

To convert in both directions, see here: Wikipedia article on ISO week dates

Robert L
A: 

Assuming the week number starts at 1

DateTime dt =  new DateTime(YearNumber, 1, 1).AddDays((WeekNumber - 1) * 7 - (WeekNumber == 1 ? 0 : 1));
return dt.AddDays(-(int)dt.DayOfWeek);

This should give you the first day in any given week. I haven't done a lot of testing on it, but looks like it works. It's smaller solution than most other's I found on the web, so wanted to share.

Nija
Jamiec
Updated the code to create a new DateTime instead of using parse. It was late. ;)
Nija