Java календарная неделя года не ISO-8601compliant?
стандарт ISO-8601 гласит, что
"первая неделя года-это неделя, содержащая первый четверг года (и, следовательно, всегда содержит 4 января)."
означает, что первая неделя года-это не та, которая содержит 1 января, но первая, которая содержит по крайней мере четыре дня в новом году.
согласно этому Пн, Январь 11 2016 находится на неделе #2. вот список номеров недель для 2016.
Ubuntu отражает это в своем виджете времени:
и команда cal также делает:
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
и больше.