System.Globalization.Calendar.GetWeekOfYear() возвращает нечетные результаты

Я нахожусь в процессе вычисления номеров недель для дат, но System.Globalization.Calendar возвращает нечетные результаты для (среди других лет) 31 декабря 2007 и 2012 годов.

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. Есть ли способ изменить это поведение в Calendar?


person sshow    schedule 10.01.2012    source источник
comment
Дни должны быть включены в неделю 1: по какому правилу? Согласно известным мне правилам, последние дни года никогда не входят в первую неделю следующего года...   -  person Thomas Levesque    schedule 10.01.2012
comment
Согласно ISO 8601. en.wikipedia.org/wiki/ISO_8601   -  person sshow    schedule 10.01.2012
comment
Кстати, почему вы используете этот странный формат даты? Кажется, я никогда не видел даты, написанные как 2007.12.29.   -  person svick    schedule 10.01.2012
comment
Ваш ответ был решен..??   -  person MethodMan    schedule 10.01.2012
comment
@svick сортирует в хронологическом порядке, когда yyyy-MM-dd, но отредактировано для удобства чтения   -  person sshow    schedule 09.05.2012


Ответы (4)


В документации по перечислению CalendarWeekRule конкретно указано, что " не сопоставляется напрямую с ISO 8601", а ссылается на Формат недели года ISO 8601 в Microsoft .Net, запись в блоге, в которой описываются различия.

person phoog    schedule 10.01.2012
comment
Это все объясняет. Спасибо - person sshow; 10.01.2012
comment
Я даже не хочу смотреть на обходной путь. Мой простой вопрос: почему? Кому это выгодно? Зачем слегка меняться, если нужно выбрать две даты из десяти, чтобы увидеть разницу? Немного смущает... - person Piddu; 12.12.2012

Посмотрите на значения CalendarWeekRule. Вы используете FirstFourDayWeek и поэтому получаете значения, которые описываете. Если вы хотите, чтобы в каждой неделе было ровно 7 дней, вы должны использовать FirstFullWeek.

В вашем случае это будет означать, что 31.12.2007 будет 53-й неделей, но так же будет и 2.1.2008.

person svick    schedule 10.01.2012
comment
Это решение не соответствует стандарту ISO 8601, поскольку первая неделя, на которую приходится большинство (четыре или более) дней в начальном году [это неделя 1] - person sshow; 10.01.2012

Начиная с .net core 3 появился новый ISOWeek, который действительно правильно вычисляет WeekOfYear.

https://docs.microsoft.com/en-us/dotnet/api/system.globalization.isoweek.getweekofyear

person dibs487    schedule 06.02.2020

Не обязательно иметь 52 недели, чтобы идентификаторы недели были уникальными, вам просто не обязательно иметь 7 дней в конкретной неделе.

Если это проблема для вас, добавьте код для обработки пограничного случая.

person Guvante    schedule 10.01.2012
comment
В неделе всегда 7 дней. - person Anders Lindén; 30.08.2018