我在谷歌上搜索了很多,找到了很多解决方案,但没有一个能告诉我2012-12-31的正确周数。即使是MSDN上的例子(链接)也失败了。

2012-12-31是星期一,所以应该是第一周,但是我尝试的每一种方法都给了我53。以下是我尝试过的一些方法:

从MDSN库:

DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;

return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);

解决方案2:

return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

解决方案3:

CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;

更新

当date为2012-12-31时,下面的方法实际返回1。换句话说,我的问题是我的方法没有遵循ISO-8601标准。

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

当前回答

一年有52周零1天,如果是一圈年(52 x 7 = 364)则为2天。2012-12-31是第53周,一周只有2天,因为2012年是一圈年。

其他回答

正如在这个MSDN页面中所指出的,ISO8601周和。net周编号之间有轻微的差异。

你可以参考MSDN博客中的这篇文章来获得更好的解释:“微软。net中的ISO 8601年度周格式”

简单地说,. net允许将周划分为年,而ISO标准不允许。 在本文中,还提供了一个简单的函数,用于获取每年最后一周的正确ISO 8601周数。

更新下面的方法实际上为2012-12-31返回1,这在ISO 8601中是正确的(例如德国)。

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
} 

在PowerShell 7.x.y中: 如果您需要匹配的WeekYear,您将需要以下两个代码行。

[System.Globalization.ISOWeek]::GetWeekOfYear((get-date))
[System.Globalization.ISOWeek]::GetYear((get-date))

一年有52周零1天,如果是一圈年(52 x 7 = 364)则为2天。2012-12-31是第53周,一周只有2天,因为2012年是一圈年。

如果您想要全球化的周数,另一个答案是: 我也把答案贴在这里了

从原来的答案:

基于这个答案:@bunny4

但并不是每个人都在美国,或者可能需要支持多种文化。 使用此解决方案来支持文化定义的周规则和第一天规则。例:丹麦有“一周的头四天”规则,“星期一”是一周的第一天。

//for now, take the the current executing thread's Culture
var cultureInfo = Thread.CurrentThread.CurrentCulture;

//let's pick a date
DateTime dt = new DateTime(2020, 12, 21);

DayOfWeek firstDay = cultureInfo.DateTimeFormat.FirstDayOfWeek;
CalendarWeekRule weekRule = cultureInfo.DateTimeFormat.CalendarWeekRule;
Calendar cal = cultureInfo.Calendar;
int week = cal.GetWeekOfYear(dt, weekRule, firstDay);

从上面il_guru的代码到Powershell端口:

function GetWeekOfYear([datetime] $inputDate)
{
   $day = [System.Globalization.CultureInfo]::InvariantCulture.Calendar.GetDayOfWeek($inputDate)
   if (($day -ge [System.DayOfWeek]::Monday) -and ($day -le [System.DayOfWeek]::Wednesday))
   {
      $inputDate = $inputDate.AddDays(3)
   }

   # Return the week of our adjusted day
   $weekofYear = [System.Globalization.CultureInfo]::InvariantCulture.Calendar.GetWeekOfYear($inputDate, [System.Globalization.CalendarWeekRule]::FirstFourDayWeek, [System.DayOfWeek]::Monday)
   return $weekofYear
}