Ось оновлення Java 8 з деяким кодом, оскільки GregorianCalendar, ймовірно, буде застарілим або вилученим із майбутніх версій JDK.
Новий код обробляється у WeekFields
класі, а саме для нижнього y
/ верхнього регістру Y
з weekBasedYear()
польовим аксесуаром.
Повертає поле для доступу до року тижневого року на основі цього WeekFields. Це представляє концепцію року, коли тижні починаються у встановлений день тижня, наприклад, у понеділок, і кожен тиждень належить рівно одному році. Це поле зазвичай використовується з dayOfWeek () і weekOfWeekBasedYear ().
Тиждень перший (1) - це тиждень, що починається з getFirstDayOfWeek (), де є принаймні дні getMinimalDaysInFirstWeek () у році. Таким чином, тиждень перший може розпочатися до початку року. Якщо перший тиждень починається після початку року, то попередній період - це останній тиждень попереднього року.
Це поле можна використовувати з будь-якою календарною системою.
На вирішальній фазі синтаксичного аналізу можна створити дату з тижня року, тижня року та дня тижня.
У строгому режимі всі три поля перевіряються відповідно до діапазону допустимих значень. Поле "тиждень року" перевіряється, щоб гарантувати, що результуючий тижневий рік є запрошеним тижні.
У розумному режимі всі три поля перевіряються відповідно до діапазону допустимих значень. Поле тижня року на основі року перевіряється від 1 до 53, що означає, що результуюча дата може бути в наступному тижні року до вказаної.
У поблажливому режимі рік і день тижня перевіряються відповідно до діапазону допустимих значень. Отримана дата обчислюється еквівалентно наступному триступеневому підходу. По-перше, створіть дату в перший день першого тижня в запитуваному тижневому році. Потім візьміть рік, заснований на тижнях тижня, відніміть один і додайте суму в тижнях до дати. Нарешті, налаштуйте правильний день тижня в межах локалізованого тижня.
Налаштування цього WeekFields
екземпляра залежить від локалі і може мати різні налаштування залежно від цього, США та європейські країни, такі як Франція, можуть мати інший день на початку тижня.
Наприклад, DateFormatterBuilder
Java 8, створіть парсер з мовою і використовуйте цю локаль для Y
символу:
public final class DateTimeFormatterBuilder {
...
private void parsePattern(String pattern) {
...
} else if (cur == 'Y') {
appendInternal(new WeekBasedFieldPrinterParser(cur, count));
} else {
...
static final class WeekBasedFieldPrinterParser implements DateTimePrinterParser {
...
private DateTimePrinterParser printerParser(Locale locale) {
WeekFields weekDef = WeekFields.of(locale);
TemporalField field = null;
switch (chr) {
case 'Y':
field = weekDef.weekBasedYear();
if (count == 2) {
return new ReducedPrinterParser(field, 2, 2, 0, ReducedPrinterParser.BASE_DATE, 0);
} else {
return new NumberPrinterParser(field, count, 19,
(count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD, -1);
}
case 'e':
case 'c':
field = weekDef.dayOfWeek();
break;
case 'w':
field = weekDef.weekOfWeekBasedYear();
break;
case 'W':
field = weekDef.weekOfMonth();
break;
default:
throw new IllegalStateException("unreachable");
}
return new NumberPrinterParser(field, (count == 2 ? 2 : 1), 2, SignStyle.NOT_NEGATIVE);
}
...
}
...
}
Ось приклад
System.out.format("Conundrum : %s%n",
ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC"))
.format(DateTimeFormatter.ofPattern("YYYYMMdd'T'HHmms'S'")));
System.out.format("Solution : %s%n",
ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC"))
.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmms'S'")));
System.out.format("JVM Locale first day of week : %s%n",
WeekFields.of(Locale.getDefault()).getFirstDayOfWeek());
System.out.format("US first day of week : %s%n",
WeekFields.of(Locale.US).getFirstDayOfWeek());
System.out.format("France first day of week : %s%n",
WeekFields.of(Locale.FRANCE).getFirstDayOfWeek());
System.out.format("JVM Locale min days in 1st week : %s%n",
WeekFields.of(Locale.getDefault()).getMinimalDaysInFirstWeek());
System.out.format("US min days in 1st week : %s%n",
WeekFields.of(Locale.US).getMinimalDaysInFirstWeek());
System.out.format("JVM Locale min days in 1st week : %s%n",
WeekFields.of(Locale.FRANCE).getMinimalDaysInFirstWeek());
System.out.format("JVM Locale week based year (big Y): %s%n",
ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")).get(WeekFields.of(Locale.FRANCE).weekBasedYear()));
System.out.format("France week based year (big Y) : %s%n",
ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")).get(WeekFields.of(Locale.FRANCE).weekBasedYear()));
System.out.format("US week based year (big Y) : %s%n",
ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC")).get(WeekFields.of(Locale.US).weekBasedYear()));
І щодо локалі і верхнього корпусу Y
, ви можете грати з опцією командного рядка -Duser.language=
( fr
, en
, es
і т.д.), або примусово локаль під час виклику:
System.out.format("English localized : %s%n",
ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC"))
.format(DateTimeFormatter.ofPattern("YYYYMMdd'T'HHmms'S'", Locale.ENGLISH)));
System.out.format("French localized : %s%n",
ZonedDateTime.of(2015, 12, 30, 0, 0, 0, 0, ZoneId.of("UTC"))
.format(DateTimeFormatter.ofPattern("YYYYMMdd'T'HHmms'S'", Locale.FRENCH)));