C# 获取周数的第一天和最后一天的日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19901666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:04:48  来源:igfitidea点击:

Get date of first and last day of week knowing week number

c#date

提问by Octavian Epure

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);            
    }

采纳答案by Tim Schmelter

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 http://stackoverflow.com/a/11155102/284240
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.

添加 6 天以获得一周的结束。

回答by user1646737

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.

由于每周有 7 天,您会知道第 10 周与第 71 - 77 天相同。您知道每个月的天数(不要忘记闰年)。构造确切的日期,然后,您可以获得有关这些日期的信息。

回答by atomaras

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

从原始 DateTime 中减去 1 年,然后再次调用 GetWeekNumber 方法。

TimeSpan oneYear = dateTime.AddYears(1) - dateTime;
var lastYearWeekNumber = GetWeekNumber(dateTime.Subtract(oneYear));

回答by Dirk Schmidt

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;
}

回答by Alexander Razvalinov

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

上述方法计算 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));
    }

回答by user2634778

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.

Tim Schmelter 的方法不适用于每周从星期一开始的瑞典 (sv-SE) 文化。这已经用 en-US 和 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);
    }

回答by Oswald

    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!

更简单、更有效的解决方案!