2009-09-30 98 views

回答

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

要知道,这是不是ISO 8601兼容。在瑞典,我们使用ISO 8601 week数字,但即使区域性设置为“SV-SE”,CalendarWeekRuleFirstFourDayWeek,并FirstDayOfWeek是周一weekNo变量将被设置为,而不是在正确的上面的代码。

我只与瑞典的设置试过,但我敢肯定,使用ISO 8601的星期数所有国家(奥地利,德国,瑞士和更多)将受此问题影响。

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

这里是一个紧凑的解决方案

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

非常好的答案。感谢 – roosteronacid 2009-09-30 12:28:19

+0

同样的问题与我认为的其他斯堪的纳维亚半岛,我是丹麦人,我想知道为什么我的测试显示31/12也是第53周,因为我的Google日历显示它的第一周。 – BerggreenDK 2013-01-16 01:01:02

+0

为什么到处使用“var”? – AndreaCi 2015-03-10 08:49:22

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

事情是这样的......

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

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

    } 

} 
1

我知道这是晚了测试,但由于它在我的搜索想出了,我想我会抛出一个不同解决方案。这是ac#解决方案。

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

这将返回“5”为日期29/12/2016 - 它应该返回52 – DNKROZ 2017-01-16 13:49:16

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也将是正确的,因为俄罗斯周周一开始。

1

如果你想在ISO 8601的周数,其中周开始与星期一,所有周七天,并每周1是包含一年的第一个星期四的一周,这可能是一个解决方案。

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

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

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

首先,((int)的date.DayOfWeek + 6)%7)确定的平日数,0 =星期一, 6 =周日。

date.AddDays( - ((int)的日期。DayOfWeek + 6)%7)确定所需星期数前面星期一的日期。

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

如果通过七(向下取整)划分一年内(从零开始)天数,你得到的(零基)周数。

在c#中,整数计算结果隐含地舍入。