Вот обновление Java 8 с некоторым кодом, поскольку GregorianCalendar, вероятно, будет исключен или удален из будущих версий JDK.
Новый код обрабатывается в классе WeekFields
, и особенно в нижнем регистре y
/ верхний регистр Y
с полем доступа weekBasedYear()
.
Возвращает поле для доступа к году недельного года на основе этого WeekFields.Это представляет концепцию года, когда недели начинаются с фиксированного дня недели, такого как понедельник, и каждая неделя принадлежит ровно одному году.Это поле обычно используется с dayOfWeek () и weekOfWeekBasedYear ().
Week one (1) - это неделя, начинающаяся с getFirstDayOfWeek (), где в году есть как минимум getMinimalDaysInFirstWeek () дней. Таким образом, первая неделя может начаться до начала года.Если первая неделя начинается после начала года, то предыдущий период относится к последней неделе предыдущего года.
Это поле можно использовать с любой календарной системой.
На этапе разрешения синтаксического анализа можно создать дату из года в неделю, недели в году и дня недели.
В строгом режиме все три поля проверяются по их диапазонудействительных значений.Поле недели года проверяется, чтобы убедиться, что итоговый недельный год является запрошенным недельным годом.
В интеллектуальном режиме все три поля проверяются по диапазону допустимых значений.Поле неделя недели на основе года проверяется от 1 до 53, что означает, что итоговая дата может быть в следующем году на основе недели к указанному.
В снисходительном режиме год идень недели проверяется по диапазону допустимых значений.Итоговая дата рассчитывается эквивалентно следующему трехэтапному подходу.Сначала создайте дату в первый день первой недели в запрашиваемом году на основе недели.Затем возьмите год недели, основанный на неделе, вычтите один и добавьте сумму в неделях к дате.Наконец, настройте правильный день недели в пределах локализованной недели.
Настройка этого экземпляра WeekFields
зависит от локали и может иметь различные настройки в зависимости от нее, США и европейских стран.например, у Франции может быть другой день в качестве начала недели.
Например, DateFormatterBuilder
в Java 8, создайте экземпляр синтаксического анализатора с языковым стандартом и используйте этот языковой стандарт для символа Y
:
public final class DateTimeFormatterBuilder {
...
private void parsePattern(String pattern) {
...
} else if (cur == 'Y') {
// Fields defined by Locale
appendInternal(new WeekBasedFieldPrinterParser(cur, count));
} else {
...
static final class WeekBasedFieldPrinterParser implements DateTimePrinterParser {
...
/**
* Gets the printerParser to use based on the field and the locale.
*
* @param locale the locale to use, not null
* @return the formatter, not null
* @throws IllegalArgumentException if the formatter cannot be found
*/
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=
(* 1043)*, 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)));