Java календарная неделя года не ISO-8601compliant?

стандарт ISO-8601 гласит, что

"первая неделя года-это неделя, содержащая первый четверг года (и, следовательно, всегда содержит 4 января)."

означает, что первая неделя года-это не та, которая содержит 1 января, но первая, которая содержит по крайней мере четыре дня в новом году.

согласно этому Пн, Январь 11 2016 находится на неделе #2. вот список номеров недель для 2016.

Ubuntu отражает это в своем виджете времени:

enter image description here

и команда cal также делает:

enter image description here

Oracle поддерживает его с параметром" iw"TO_CHAR:

> select to_char(to_date('11/01/2016','dd/mm/yyyy'),'iw') weekno from dual;
> WEEKNO
    02

но Java говорит Пн, Январь 11 2016 Неделя #3

Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
System.out.println(c.get(Calendar.WEEK_OF_YEAR));

Output:
Mon Jan 11 09:02:35 VET 2016
3

Java думает, что первая неделя года-это та, которая содержит 1 января.

- Is есть ли способ для Java использовать нумерацию недели ISO-8601-copliant?

2 ответов


как я отметил в своем комментарии,по умолчанию - это определенный языковой стандарт. Некоторые локалы дадут 3, некоторые дадут 2.

к счастью, вы можете указать количество дней, которое должно присутствовать в первую неделю года, для данного Calendar. Как вы пишете выше, Для ISO 8601 это число равно 4, таким образом, должен работать следующий код:

Calendar c = Calendar.getInstance();
c.setMinimalDaysInFirstWeek(4); // For ISO 8601
System.out.println(c.getTime());
System.out.println(c.get(Calendar.WEEK_OF_YEAR));

это должно сделать вывод правильным независимо от локали.


tl; dr

myZonedDateTime.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) 

...и...

myZonedDateTime.get( IsoFields.WEEK_BASED_YEAR )

избегайте устаревших классов даты и времени

как правильный ответ от haraldK поясняю:Calendar определение класса недели зависит от локали. Несмотря на благие намерения, это сбивает с толку.

вы должны избегать Calendar и связанные классы, такие как Date. Теперь они вытеснены java.время классы.

ISO 8601 неделя

как ISO 8601 неделя, было ясно, что означает:

  • первый день-понедельник, проходит через воскресенье.
  • неделя номер один из недели на основе года содержит первый четверг календарного года.
  • недели базируемый год или 52 или 53 недели.
  • первые / последние несколько дней календарного года могут появиться на предыдущей / следующей неделе год.

java.время

на java.время классы включают ограниченную поддержку ISO 8601 стандартные недели. Вызовите get метод на различных классах, таких как LocalDate и ZonedDateTime. Пройти TemporalField реализации, найденные как константы в IsoFields класс.

int week = myZonedDateTime.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int weekBasedYear = myZonedDateTime.get( IsoFields.WEEK_BASED_YEAR ) ;

ThreeTen-Extra

еще лучше добавьте ThreeTen-Extra библиотека для вашего проекта, чтобы использовать YearWeek класса.

org.threeten.extra.YearWeek yw = YearWeek.from( myZonedDateTime ) ;

остерегайтесь настройки программного обеспечения календаря

никогда не принимайте определение числа недели. Убедитесь, что источник такого числа имеет то же определение недели, что и вы, например определение ISO 8601.

например, the календарь приложение поставляется Apple с macOS по умолчанию используется" григорианское " определение календаря недели. Что касается того, что это означает, Я не знаю, поскольку я не смог найти никакой документации об их намерении/определении. Для ISO 8601 недель, вы должны изменить настройку по умолчанию.


о java.время

на java.время framework встроен в Java 8 и позже. Эти классы вытесняют беспокойных старых наследие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

на Joda Времени, теперь режим обслуживания, советует миграцию в java.время классы.

чтобы узнать больше, см. В Oracle Учебник. И поиск стека Переполнение для многих примеров и объяснений. Спецификация JSR 310.

С помощью драйвер JDBC соответствуют JDBC 4.2 или позже вы можете обменять java.время объекты непосредственно с вашей базой данных. Нет необходимости в строках или java.язык SQL.* учебные занятия.

где получить java.время занятий?

  • Java SE 8, Java SE 9, и позже
    • встроенный.
    • часть стандартного API Java со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • большая часть java.функциональность времени обратно портирована на Java 6 & 7 в ThreeTen-Backport.
  • Android
    • более поздние версии Android bundle реализации java.классы время.
    • для более раннего Android,ThreeTenABP проект приспосабливается ThreeTen-Backport (упоминалось выше). См.как использовать ThreeTenABP....

на ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательной площадкой для возможных будущих дополнений к java.время. Здесь вы можете найти полезные классы, такие как Interval, YearWeek, YearQuarter и больше.