Get date of first and last day of week knowing week number
Asked Answered
D

9

14

I need to get the date of the first and last day of the week knowing the week number.

I get a start date and an end date, representing the first and last day of a selected week in a given year. then I need to get the start date and end date of the same week of the previous year to do a graphical comparison of some data.

I managed to get the week number based on the given start date and end date. Now I need to get the date of the first day and last day of the same week of the previous year. How could I do this quickest ?

EDIT: This is how I got the week number:

 private int GetWeekNumber(DateTime date)
    {
        GregorianCalendar calendar = new GregorianCalendar(GregorianCalendarTypes.USEnglish);
        return calendar.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);            
    }
Doormat answered 11/11, 2013 at 8:15 Comment(0)
H
30

You can use following two methods to calculate the week-number and the start-date of a given weeknumber according to a given year:

// this method is borrowed from https://mcmap.net/q/99287/-get-the-correct-week-number-of-a-given-date
public static int GetIso8601WeekOfYear(DateTime time)
{
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
} 

public static DateTime FirstDateOfWeek(int year, int weekOfYear, System.Globalization.CultureInfo ci)
{
    DateTime jan1 = new DateTime(year, 1, 1);
    int daysOffset = (int)ci.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;
    DateTime firstWeekDay = jan1.AddDays(daysOffset);
    int firstWeek = ci.Calendar.GetWeekOfYear(jan1, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek);
    if ((firstWeek <= 1 || firstWeek >= 52) && daysOffset >= -3)
    {
        weekOfYear -= 1;
    }
    return firstWeekDay.AddDays(weekOfYear * 7);
}

Then you can get both dates in the following way:

// 46
int thisWeekNumber = GetIso8601WeekOfYear(DateTime.Today); 
// 11/11/2013  
DateTime firstDayOfWeek= FirstDateOfWeek(2013, thisWeekNumber, CultureInfo.CurrentCulture); 
// 11/12/2012  
DateTime firstDayOfLastYearWeek = FirstDateOfWeek(2012, thisWeekNumber, CultureInfo.CurrentCulture);   

Add 6 days to get the end of the week.

Howes answered 11/11, 2013 at 8:29 Comment(6)
how could I make this work for the US Calendar, where Sunday is the first day of week ? Is this as simple as replacing all references to DayOfWeek.Monday with DayOfWeek.Sunday ?Doormat
@OctavianEpure: That method returns the week number according to ISO 8601. But if you have already a method to get the week-number you just need my second method which supports a CultureInfo as parameter. Just pass CultureInfo.CurentCulture or CultureInfo.CreateSpecificCulture("en-US"). I have just shown my method to retrieve the week number since you haven't showed yours.Howes
I vave shown my method to get week number in my edited answer. Thank you very much for your post. I will try it out as soon as I start overall testing.Doormat
This method fails for 1st week of 2006. I've tested the following correction against 2012-01 until 2025-52 range. if ((firstWeek <= 1 || firstWeek >= 52) && daysOffset >= -3)Energize
hi given today, how to get the first date of weekSlattern
I was getting wrong answer for 2/25/22, was returning 2/27/22 not 2/20/22 as expectedGarganey
P
27

This is my solution:

public static DateTime FirstDayOfWeek(DateTime date)
{
    DayOfWeek fdow = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
    int offset = fdow - date.DayOfWeek;
    DateTime fdowDate = date.AddDays(offset);
    return fdowDate;
}

public static DateTime LastDayOfWeek(DateTime date)
{
    DateTime ldowDate = FirstDayOfWeek(date).AddDays(6);
    return ldowDate;
}
Passementerie answered 25/11, 2014 at 10:32 Comment(6)
By far the best answerSlumlord
FirstDayOfWeek is giving the first day of the next week if "date" is a Sunday.Arielle
@MxFragz: Please provide an example. I can't reproduce your problem.Cornwell
this is the correct offset: var offset = -1 * (7 + ((dateTime.DayOfWeek - firstDayOfWeek) % 7))Percheron
This doesn't directly answer the poster's original question, which was how to get the first and last days of the week when you have the week number, not the date.Pantry
Agree with @MxFragz, it doesn't work if first day is Sunday.Affenpinscher
M
2

The method above calculates first date wrong for 1st week of 2016.

Fixed code based on previous answers

 public DateTime FirstDateOfWeek(
        int year,
        int weekOfYear)
    {
        var newYear = new DateTime(year, 1, 1);
        var weekNumber = newYear.GetIso8601WeekOfYear(); 

        DateTime firstWeekDate;

        if (weekNumber != 1)
        {
            var dayNumber = (int) newYear.DayOfWeek;
            firstWeekDate = newYear.AddDays(7 - dayNumber + 1);
        }
        else
        {
            var dayNumber = (int)newYear.DayOfWeek;
            firstWeekDate = newYear.AddDays(-dayNumber + 1);
        }

        if (weekOfYear == 1)
        {
            return firstWeekDate;
        }

        return firstWeekDate.AddDays(7 * (weekOfYear - 1));
    }

Plus test

    [TestCase(2016, 1, 2016, 1, 4)]
    [TestCase(2016, 2, 2016, 1, 11)]
    [TestCase(2016, 52, 2016, 12, 26)]
    [TestCase(2014, 1, 2013, 12, 30)]
    public void FirstDateOfWeek_ShouldReturnCorrectDay(int year, int weekNumber, int correctYear, int correctMonth, int correctDay)
    {
        var helper = new DateHelper();
        var result = helper.FirstDateOfWeek(year, weekNumber);

        Assert.That(result.Year, Is.EqualTo(correctYear));
        Assert.That(result.Month, Is.EqualTo(correctMonth));
        Assert.That(result.Day, Is.EqualTo(correctDay));
    }
Madden answered 11/1, 2016 at 17:12 Comment(1)
Please be more specific. The "method above" is very relative.Cornwell
C
1
    private static DateTime FirstDateOfWeek(int year, int weekOfYear)
    {
        var firstDate = new DateTime(year, 1, 4);
        //first thursday of the week defines the first week (https://en.wikipedia.org/wiki/ISO_8601)
        //Wiki: the 4th of january is always in the first week
        while (firstDate.DayOfWeek != DayOfWeek.Monday)
            firstDate = firstDate.AddDays(-1);

        return firstDate.AddDays((weekOfYear - 1)*7);
    }

Easyer and more efficient solution!

Catalogue answered 6/6, 2016 at 14:12 Comment(0)
E
0

Subtract 1 year from your original DateTime and call your GetWeekNumber method again with that.

TimeSpan oneYear = dateTime.AddYears(1) - dateTime;
var lastYearWeekNumber = GetWeekNumber(dateTime.Subtract(oneYear));
Ergonomics answered 11/11, 2013 at 8:31 Comment(0)
P
0

You can find the solution for how to get the first and last date of the current or last week as per the passed argument date and now you can also get the date of the first day and last day of the same week of the previous year.

You can also change some settings to change your first weekday to get results as your need.

Suppose your weekday starts from Monday except for Sunday, so what you need to do is that just change the switch cases and go on to get your desired result.

public DateTime GetFirstDateOfCurrentWeek(DateTime dtDate)
{
 //In this function we assumed that week start from sunday and end on saturday
    int no = 0;
    switch (dtDate.DayOfWeek.ToString())
    {
        case "Sunday":
            no = 0;
            break;
        case "Monday":
            no = 1;
            break;
        case "Tuesday":
            no = 2;
            break;
        case "Wednesday":
            no = 3;
            break;
        case "Thursday":
            no = 4;
            break;
        case "Friday":
            no = 5;
            break;
        case "Saturday":
            no = 6;
            break;
        default:
            no = 0;
            break;
    }
    return dtDate.AddDays(-no);
 }

public DateTime GetLastDateOfCurrentWeek(DateTime dtDate)
{
    int no = 0;
    switch (dtDate.DayOfWeek.ToString())
    {
        case "Saturday":
            no = 0;
            break;
        case "Friday":
            no = 1;
            break;
        case "Thursday":
            no = 2;
            break;
        case "Wednesday":
            no = 3;
            break;
        case "Tuesday":
            no = 4;
            break;
        case "Monday":
            no = 5;
            break;
        case "Sunday":
            no = 6;
            break;
        default:
            no = 0;
            break;
    }
    return dtDate.AddDays(no);
}

public DateTime GetFirstDateOfLastWeek(DateTime dtDate)
{
    return GetFirstDateOfCurrentWeek(dtDate).AddDays(-7);
}

public DateTime GetLastDateOfLastWeek(DateTime dtDate)
{
    return GetLastDateOfCurrentWeek(dtDate).AddDays(-7);
}

public DateTime GetFirstDateOfCurrentWeekOfPrvYear(DateTime dtDate)
{
    int dayOfYear = dtDate.DayOfYear;
    DateTime firstDateOfThisYear = (Convert.ToDateTime("01/01/" + dtDate.Year.ToString()));
    DateTime firstDateofPrvYear = (firstDateOfThisYear.AddYears(-1));
    DateTime dateOfPrvYear = (firstDateofPrvYear.AddDays(dayOfYear));

    return GetFirstDateOfCurrentWeek(dateOfPrvYear);
}

public DateTime GetLastDateOfCurrentWeekOfPrvYear(DateTime dtDate)
{
    int dayOfYear = dtDate.DayOfYear;
    DateTime firstDateOfThisYear = Convert.ToDateTime("01/01/" + dtDate.Year.ToString());
    DateTime firstDateofPrvYear = (firstDateOfThisYear.AddYears(-1));
    DateTime dateOfPrvYear = (firstDateofPrvYear.AddDays(dayOfYear));

    return GetLastDateOfCurrentWeek(dateOfPrvYear);
}

DateTime dt = Convert.ToDateTime("12/12/2019");

int dayOfYear = dt.DayOfYear;
string weekOfYear = (dt.DayOfYear / 7).ToString();
string firstDateOfThisYear = (Convert.ToDateTime("01/01/" + dt.Year.ToString())).ToShortDateString();
string firstDateofPrvYear = (Convert.ToDateTime(firstDateOfThisYear).AddYears(-1)).ToShortDateString();
string dateOfPrvYear = (Convert.ToDateTime(firstDateofPrvYear).AddDays(dayOfYear)).ToShortDateString();
string firstDateofWeekPrvYear = GetFirstDateOfCurrentWeek(Convert.ToDateTime(dateOfPrvYear)).ToShortDateString();
string lastDateofWeekPrvYear = GetLastDateOfCurrentWeek(Convert.ToDateTime(dateOfPrvYear)).ToShortDateString();
string weekOfPrvYear = (Convert.ToDateTime(dateOfPrvYear).DayOfYear / 7).ToString();

MessageBox.Show("Day of Year: " + dayOfYear.ToString());
MessageBox.Show("Week of Year: " + weekOfYear);
MessageBox.Show("First day of this year: " + firstDateOfThisYear);
MessageBox.Show("First day of prv year: " + firstDateofPrvYear);
MessageBox.Show("Date of Prv Year: " + dateOfPrvYear);
MessageBox.Show("First Date of Week Prv Year: " + firstDateofWeekPrvYear);
MessageBox.Show("Last Date of Week Prv Year: " + lastDateofWeekPrvYear);
MessageBox.Show("Day of Prv Year: " + weekOfPrvYear.ToString());
Pillbox answered 2/12, 2020 at 10:0 Comment(0)
D
0

I have the following hardcoded solution only for my culture, which returns an anonymous type with the number of the week, the first and last date of this week.

var weekNumbers = new List<int>() {1, 2, 3, 4, 5};
var year = DateTime.Now.Year;
var dates = weekNumbers.Select(wn => new {
     WeekNumber = wn, 
     StartWeekDate = DateOnly.FromDateTime(ISOWeek.ToDateTime(year, wn, DayOfWeek.Monday)), 
     EndWeekDate = DateOnly.FromDateTime(ISOWeek.ToDateTime(year, wn, DayOfWeek.Sunday)) 
 }).OrderBy(e=>e.WeekNumber).ToList();
Drafty answered 10/3 at 14:2 Comment(0)
I
-1

Since there are 7 days per week, you will know that Week 10 is the same as days 71 - 77. You know the number of days per month (don't forget leap year). Construct the exact dates and then, you can get information about those days.

Individualize answered 11/11, 2013 at 8:20 Comment(3)
Are you sure about that? What happens if the first of january is on a Friday?Annis
Presumably, the OP knows this because he says he can get the week number. To be able to do that, I assume he had to know when the first week started. On the flip-side, you can find out the day of the week for January 1 of any given year. Then, you need to set the rule: Is this your first week, or do you need to go to the next Monday to start the first week?Individualize
Somebody care to explain the down-vote? If OP knows he is in week 43, then obviously, he needs to know that Friday, January 1, is either the 1st week of the year or the 2nd week, depending on whatever rule he desires to establish and follow. The rest is just math.Individualize
C
-1

Tim Schmelter's method didn't work for Swedish (sv-SE) culture where weeks start on Mondays. This has been tested with en-US and sv-SE.

    public static DateTime GetFirstDateOfWeek(int year, int weekOfYear, CultureInfo cultureInfo)
    {
        DateTime jan1 = new DateTime(year, 1, 1);
        int daysOffset = (int)cultureInfo.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;
        DateTime firstWeekDay = jan1.AddDays(daysOffset);
        int firstWeek = cultureInfo.Calendar.GetWeekOfYear(jan1, cultureInfo.DateTimeFormat.CalendarWeekRule, cultureInfo.DateTimeFormat.FirstDayOfWeek);
        if (firstWeek == 1)
        {
            weekOfYear -= 1;
        }
        return firstWeekDay.AddDays(weekOfYear * 7);
    }
Creatural answered 10/2, 2016 at 15:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.