System.Globalization.Calendar.GetWeekOfYear() 返回奇怪的结果。

18

我正在计算日期的周数,但是System.Globalization.Calendar在2007年和2012年的12月31日等日期上返回了奇怪的结果。

Calendar calendar = CultureInfo.InvariantCulture.Calendar;
var date = new DateTime(2007, 12, 29);
for (int i = 0; i < 5; i++)
{
    int w = calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    Console.WriteLine("{0}\t{1}", date.ToString("dd.MM.yyyy"), w);
    date = date.AddDays(1);
}

结果

29.12.2007      52
30.12.2007      52
31.12.2007      53 <--
01.01.2008       1
02.01.2008       1

29.12.2012      52
30.12.2012      52
31.12.2012      53 <--
01.01.2013       1
02.01.2013       1

据我所知,2007年和2012年没有第53周,但这些天应该包括在第1周中。在日历中是否有更改此行为的方法?

2
“这些天应该算作第一周”: 根据哪个规则?根据我所知道的规则,一年中的最后几天从来不会被算作下一年的第一周。 - Thomas Levesque
4
根据ISO 8601的规定,该标准是用来表达日期、时间和日期时间的国际标准。它使用一个统一的日期时间格式,并且具有易读性和可排序性。该标准还包括时区和周次的表示方法。 - sshow
顺便问一句,你为什么要使用那种奇怪的日期格式?我觉得我从来没有见过日期写成"2007.12.29"。 - svick
你的问题解决了吗? - MethodMan
@svick 当 yyyy-MM-dd 时,它按时间顺序排序,但为了可读性进行了编辑。 - sshow
4个回答

16

这解释了一切。谢谢。 - sshow
9
我甚至不想看这个变通方法。我的简单问题是:为什么?谁从中受益?为什么要轻微更改,以致于你必须在十个日期中选择两个日期才能看到差异?有点令人沮丧... - Piddu
@Piddu 很可能是因为实现它的团队不知道这个标准,而在发布后,他们不想对逻辑进行重大更改。这与 .NET 实现 Unicode 的方式形成了对比,因为它早于标准而不符合标准。(我不确定 ISO 8601 在 .NET 逻辑实现之后是否有所改变,但 ISO 在 1976 年规范了计算周数的方法,因此这似乎不太可能。值得注意的是,ISO 标准将一周的开始定为星期一,这与美国的做法相冲突。) - phoog

2
请查看CalendarWeekRule的值。您正在使用FirstFourDayWeek,因此您得到了您描述的值。如果您希望每周恰好有7天,则应使用FirstFullWeek
在您的情况下,这意味着2007年12月31日将是第53周,而2008年1月2日也将是第53周。

1
该解决方案不符合ISO 8601标准,因为*第一周大多数(四天或更多)的日期在起始年份内[即为第1周]*。 - sshow

1

0

周标识符不必为52周才能保持唯一性,你并不一定要在特定的一周内拥有7天。

如果这对你来说是个问题,那么请添加代码来处理边缘情况。


一周总共有七天。 - Anders Lindén

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接