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

C# 如何计算/查找给定日期的周数?,c#,asp.net,date,C#,Asp.net,Date,如何计算/查找给定日期的周数 My.Computer.Info.InstalledUICulture.DateTimeFormat.Calendar.GetWeekOfYear(yourDateHere, CalendarWeekRule.FirstDay, My.Computer.Info.InstalledUICulture.DateTimeFormat.FirstDayOfWeek) 类似这样的东西…在MSDN上查看有以下示例: public static int GetWeekNu

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

My.Computer.Info.InstalledUICulture.DateTimeFormat.Calendar.GetWeekOfYear(yourDateHere, CalendarWeekRule.FirstDay, My.Computer.Info.InstalledUICulture.DateTimeFormat.FirstDayOfWeek)
类似这样的东西…

在MSDN上查看有以下示例:

  public static int GetWeekNumber(DateTime dtPassed)
  {
          CultureInfo ciCurr = CultureInfo.CurrentCulture;
          int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
          return weekNum;
  }
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 );

   }

}
请注意,这是不兼容的。在瑞典,我们使用ISO 8601数字,但即使文化设置为“sv SE”,
CalendarWeekRule
FirstFourDayWeek
,而
FirstDayOfWeek
为星期一,weekNo变量将设置为53,而不是上述代码中正确的1

我只在瑞典的设置中尝试过这个方法,但我很确定所有使用ISO8601周编号的国家(奥地利、德国、瑞士等)都会受到这个问题的影响

对这个问题有不同的解决方案

这是一个简洁的解决方案

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);
}
它已经在以下日期进行了测试

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));
}
var datesAndISO8601Weeks=新字典
{
{新日期时间(2000,12,31),52},
{新日期时间(2001,1,1),1},
{新日期时间(2005年1月1日),53},
{新日期时间(2007,12,31),1},
{新日期时间(2008年12月29日),1},
{新日期时间(2010年1月3日),53},
{新日期时间(2011年12月31日),52},
{新日期时间(2012年1月1日),52},
{新日期时间(2013,1,2),1},
{新日期时间(2013年12月31日),1},
};
foreach(var dateWeek在datesAndISO8601Weeks中)
{
Assert(WeekOfYearISO8601(dateWeek.Key)=dateWeek.Value,dateWeek.Key.ToShortDateString()+“应该是周数”+dateWeek.Value+,但却是“+WeekOfYearISO8601(dateWeek.Key));
}

我知道这已经很晚了,但因为它是在我的搜索中出现的,所以我想我会抛出一个不同的解决方案。这是一个c#解决方案

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

var cultureInfo=cultureInfo.CurrentCulture; var calendar=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;

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

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

(int)(Math.Ceiling((decimal)startDate.Day / 7)) + (((new DateTime(startDate.Year, startDate.Month, 1).DayOfWeek) > startDate.DayOfWeek) ? 1 : 0);  
由于似乎没有一种.Net文化可以产生正确的ISO-8601周数,我建议评级者一起绕过内置的周数确定,手动进行计算,而不是尝试更正部分正确的结果

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

public static int getISO8601周号(此日期时间日期)
{var星期四=date.AddDays(3-((int)date.DayOfWeek+6)%7);
返回1+(每年的星期四-1)/7;
}
首先,((int)date.DayOfWeek+6)%7)确定工作日编号,0=周一,6=周日

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

三天后是目标周四,它决定了本周的年份

如果将一年中的(零基)天数除以七(四舍五入),则得到一年中的(零基)周数


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

斯堪的纳维亚其他国家也有同样的问题,我想,我是丹麦人,我想知道为什么我的测试显示31/12也是第53周,因为我的谷歌日历显示了它的第1周。为什么使用“var”无处不在?因为它比
字典日期和ISO8601Weeks=new Dictionary()更容易阅读,重复性更少我之所以对简单类型这样做,是因为它保持了代码的一致性。还可以添加一点,即使用var强制您选择好的变量名。这将在2016年12月29日返回“5”-它应该返回52