C# 如何计算/找到给定日期的周数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1497586/
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-06 18:08:09  来源:igfitidea点击:

How can I calculate/find the week-number of a given date?

c#asp.netdate

提问by cllpse

How can I calculate/find the week-number of a given date?

如何计算/找到给定日期的周数?

采纳答案by Jonas Elfstr?m

var currentCulture = CultureInfo.CurrentCulture;
var weekNo = currentCulture.Calendar.GetWeekOfYear(
                new DateTime(2013, 12, 31),
                currentCulture.DateTimeFormat.CalendarWeekRule,
                currentCulture.DateTimeFormat.FirstDayOfWeek);

Be aware that this is notISO 8601compatible. In Sweden we use ISO 8601 weeknumbers but even though the culture is set to "sv-SE", CalendarWeekRuleis FirstFourDayWeek, and FirstDayOfWeekis Monday the weekNovariable will be set to 53instead of the correct 1in the above code.

要知道,这是不是ISO 8601兼容。在瑞典,我们使用 ISO 8601数,但即使文化设置为“sv-SE”、CalendarWeekRuleisFirstFourDayWeekFirstDayOfWeekis 星期一,在上述代码中,weekNo变量将设置为53而不是正确的1

I have only tried this with Swedish settings but I'm pretty sure that all countries (Austria, Germany, Switzerland and more) using ISO 8601 week numbers will be affected by this problem.

我只在瑞典设置下尝试过这个,但我很确定所有使用 ISO 8601 周数的国家(奥地利、德国、瑞士等)都会受到这个问题的影响。

Peter van Ooijenand Shawn Steelehas different solutions to this problem.

Peter van OoijenShawn Steele对这个问题有不同的解决方案。

Here's a compact solution

这是一个紧凑的解决方案

private static int WeekOfYearISO8601(DateTime date)
{
    var day = (int)CultureInfo.CurrentCulture.Calendar.GetDayOfWeek(date);
    return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date.AddDays(4 - (day == 0 ? 7 : day)), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

It's been tested for the following dates

它已经过以下日期的测试

var datesAndISO8601Weeks = new Dictionary<DateTime, int>
                        {
                            {new DateTime(2000, 12, 31), 52},
                            {new DateTime(2001, 1, 1), 1},
                            {new DateTime(2005, 1, 1), 53},
                            {new DateTime(2007, 12, 31), 1},
                            {new DateTime(2008, 12, 29), 1},
                            {new DateTime(2010, 1, 3), 53},
                            {new DateTime(2011, 12, 31), 52},
                            {new DateTime(2012, 1, 1), 52},
                            {new DateTime(2013, 1, 2), 1},
                            {new DateTime(2013, 12, 31), 1},
                        };

foreach (var dateWeek in datesAndISO8601Weeks)
{
    Debug.Assert(WeekOfYearISO8601(dateWeek.Key) == dateWeek.Value, dateWeek.Key.ToShortDateString() + " should be week number " + dateWeek.Value + " but was " + WeekOfYearISO8601(dateWeek.Key));
}

回答by Bobby

My.Computer.Info.InstalledUICulture.DateTimeFormat.Calendar.GetWeekOfYear(yourDateHere, CalendarWeekRule.FirstDay, My.Computer.Info.InstalledUICulture.DateTimeFormat.FirstDayOfWeek)

Something like this...

像这样的东西...

回答by Andriy Tkach

  public static int GetWeekNumber(DateTime dtPassed)
  {
          CultureInfo ciCurr = CultureInfo.CurrentCulture;
          int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
          return weekNum;
  }

回答by SwDevMan81

Check out GetWeekOfYearon MSDN has this example:

查看MSDN 上的GetWeekOfYear有这个例子:

using System;
using System.Globalization;


public class SamplesCalendar  {

   public static void Main()  {

      // Gets the Calendar instance associated with a CultureInfo.
      CultureInfo myCI = new CultureInfo("en-US");
      Calendar myCal = myCI.Calendar;

      // Gets the DTFI properties required by GetWeekOfYear.
      CalendarWeekRule myCWR = myCI.DateTimeFormat.CalendarWeekRule;
      DayOfWeek myFirstDOW = myCI.DateTimeFormat.FirstDayOfWeek;

      // Displays the number of the current week relative to the beginning of the year.
      Console.WriteLine( "The CalendarWeekRule used for the en-US culture is {0}.", myCWR );
      Console.WriteLine( "The FirstDayOfWeek used for the en-US culture is {0}.", myFirstDOW );
      Console.WriteLine( "Therefore, the current week is Week {0} of the current year.", myCal.GetWeekOfYear( DateTime.Now, myCWR, myFirstDOW ));

      // Displays the total number of weeks in the current year.
      DateTime LastDay = new System.DateTime( DateTime.Now.Year, 12, 31 );
      Console.WriteLine( "There are {0} weeks in the current year ({1}).", myCal.GetWeekOfYear( LastDay, myCWR, myFirstDOW ), LastDay.Year );

   }

}

回答by GAdams

I know this is late, but since it came up in my search I thought I would throw a different solution in. This was a c# solution.

我知道这已经晚了,但由于它出现在我的搜索中,我想我会提出一个不同的解决方案。这是 ac# 解决方案。

(int)(Math.Ceiling((decimal)startDate.Day / 7)) + (((new DateTime(startDate.Year, startDate.Month, 1).DayOfWeek) > startDate.DayOfWeek) ? 1 : 0);??

回答by Donskikh Andrei

var cultureInfo = CultureInfo.CurrentCulture; var calendar = cultureInfo.Calendar;

var cultureInfo = CultureInfo.CurrentCulture; var 日历 =cultureInfo.Calendar;

        var calendarWeekRule = cultureInfo.DateTimeFormat.CalendarWeekRule;
        var firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
        var lastDayOfWeek = cultureInfo.LCID == 1033 //En-us
            ? DayOfWeek.Saturday
            : DayOfWeek.Sunday;

        var lastDayOfYear = new DateTime(date.Year, 12, 31);

         //Check if this is the last week in the year and it doesn`t occupy the whole week
        var weekNumber = calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek);
        return weekNumber == 53 && lastDayOfYear.DayOfWeek != lastDayOfWeek 
               ? 1 
               : weekNumber;

It works well both for US and Russian cultures. ISO 8601 also will be correct, `cause Russian week starts at Monday.

它适用于美国和俄罗斯文化。ISO 8601 也将是正确的,因为俄罗斯周从星期一开始。

回答by realbart

If you want the ISO 8601 Week Number, in which weeks start with a monday, all weeks are seven days, and week 1 is the week containing the first thursday of the year, this may be a solution.

如果您想要 ISO 8601 周数,其中周从星期一开始,所有周都是 7 天,第 1 周是包含一年中第一个星期四的周,这可能是一个解决方案。

Since there doesn't seem to be a .Net-culture that yields the correct ISO-8601 week number, I'd rater bypass the built in week determination alltogether, and do the calculation manually, instead of atempting to correct a partially correct result.

由于似乎没有产生正确 ISO-8601 周数的 .Net 文化,我将评估者完全绕过内置的周确定,并手动进行计算,而不是尝试更正部分正确的结果.

What I ended up with is the following extension method:

我最终得到的是以下扩展方法:

public static int GetIso8601WeekNumber(this DateTime date)
{    var thursday = date.AddDays(3 - ((int)date.DayOfWeek + 6) % 7);
     return 1 + (thursday.DayOfYear - 1) / 7;
}

First of all, ((int)date.DayOfWeek + 6) % 7) determines the weekday number, 0=monday, 6=sunday.

首先,((int)date.DayOfWeek + 6) % 7) 决定了星期几,0=星期一,6=星期日。

date.AddDays(-((int)date.DayOfWeek + 6) % 7) determines the date of the monday preceiding the requested week number.

date.AddDays(-((int)date.DayOfWeek + 6) % 7) 确定请求周数之前的星期一的日期。

Three days later is the target thursday, which determines what year the week is in.

三天后是目标星期四,它决定了一周在哪一年。

If you divide the (zero based) day-number within the year by seven (round down), you get the (zero based) week number in the year.

如果将一年中的(从零开始的)天数除以七(向下取整),您将得到一年中的(从零开始的)周数。

In c#, integer calculation results are round down implicitly.

在 c# 中,整数计算结果是隐式向下舍入的。