Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: sshowОтветов: 4

Я нахожусь в процессе вычисления номеров недель для дат, но 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?

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

calendarweek-number

Ответы

Ответ 1 · рейтинг 15 · phoog

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

Ответ 2 · рейтинг 2 · svick

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

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

Ответ 3 · рейтинг 1 · dibs487

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

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

Ответ 4 · Guvante

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы