Jes*_*ann 17 .net c# date-arithmetic
我有一个相当奇怪的问题.我住在丹麦,这里2013年的第一周(第1周)开始于2012年12月31日,持续7天 - 几周通常做:)
据.NET称,12月30日是第52周,第31周是第53周,1月1日是第1周.
第53周仅持续一天,第1周持续6天.显然,这一定是错误的(一周不到7天),在丹麦语中肯定是错误的.12月31日是第1周,而不是第53周.
以下代码说明了问题(CurrentCulture是"da-DK")
static void Main(string[] args)
{
//Here I get Monday
DayOfWeek firstDayOfWeek = DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek;
//Here I get FirstFourDayWeek
CalendarWeekRule weekRule = DateTimeFormatInfo.CurrentInfo.CalendarWeekRule;
DateTime date = new DateTime(2012,12,30);
for (int i = 0; i <= 10; i++)
{
DateTime currentDate = date.AddDays(i);
Console.WriteLine("Date: {0} WeekNumber: {1}",
currentDate.ToShortDateString(),
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(currentDate, weekRule, firstDayOfWeek));
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
我做错了什么或者这是.NET中的错误?如果是后者 - 您是否有正确计算周数的建议?
slo*_*oth 21
问题是该GetWeekOfYear方法不符合ISO 8601,这是您所期望的,但事实并非如此.
请注意,在您使用时FirstFourDayWeek,文档说:
基于FirstFourDayWeek值的第一周可以有四到七天.
这违反了ISO 8601规则,所有周都必须有七天.

您可以使用以下方法根据ISO 8601获取正确的周数:
int weekNumber(DateTime fromDate)
{
// Get jan 1st of the year
DateTime startOfYear = fromDate.AddDays(- fromDate.Day + 1).AddMonths(- fromDate.Month +1);
// Get dec 31st of the year
DateTime endOfYear = startOfYear.AddYears(1).AddDays(-1);
// ISO 8601 weeks start with Monday
// The first week of a year includes the first Thursday
// DayOfWeek returns 0 for sunday up to 6 for saterday
int[] iso8601Correction = {6,7,8,9,10,4,5};
int nds = fromDate.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek];
int wk = nds / 7;
switch(wk)
{
case 0 :
// Return weeknumber of dec 31st of the previous year
return weekNumber(startOfYear.AddDays(-1));
case 53 :
// If dec 31st falls before thursday it is week 01 of next year
if (endOfYear.DayOfWeek < DayOfWeek.Thursday)
return 1;
else
return wk;
default : return wk;
}
}
Run Code Online (Sandbox Code Playgroud)
来源(还有很多其他功能......)
所以,将你的循环改为
for (int i = 0; i <= 10; i++)
{
DateTime currentDate = date.AddDays(i);
Console.WriteLine("Date: {0} WeekNumber: {1}: CorrectWeekNumber: {2}",
currentDate.ToShortDateString(),
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(currentDate, weekRule, firstDayOfWeek),
weekNumber(currentDate));
}
Run Code Online (Sandbox Code Playgroud)
将导致:
日期:30.12.2012 WeekNumber:52:CorrectWeekNumber:52
Date:31.12.2012 WeekNumber:53:CorrectWeekNumber:1
Date:01.01.2013 WeekNumber:1:CorrectWeekNumber:1
Date:02.01.2013 WeekNumber:1:CorrectWeekNumber:1
Date: 03.01.2013 WeekNumber:1:CorrectWeekNumber:1
Date:04.01.2013 WeekNumber:1:CorrectWeekNumber:1
Date:05.01.2013 WeekNumber:1:CorrectWeekNumber:1
Date:06.01.2013 WeekNumber:1:CorrectWeekNumber:1
Date:07.01. 2013 WeekNumber:2:CorrectWeekNumber:2
Date:08.01.2013 WeekNumber:2:CorrectWeekNumber:2
Date:09.01.2013 WeekNumber:2:CorrectWeekNumber:2