Oto aktualizacja Java 8 z pewnym kodem, ponieważ GregorianCalendar prawdopodobnie zostanie wycofany lub usunięty z przyszłych wersji JDK.
Nowy kod jest obsługiwany w WeekFields
klasie, a szczególnie w przypadku małych y
/ dużych liter Y
z weekBasedYear()
akcesorium pola.
Zwraca pole umożliwiające dostęp do roku w roku opartym na tygodniu na podstawie tego WeekFields. Stanowi to koncepcję roku, w którym tygodnie rozpoczynają się w ustalonym dniu tygodnia, takim jak poniedziałek, a każdy tydzień należy do dokładnie jednego roku. To pole jest zwykle używane z właściwościami dayOfWeek () i weekOfWeekBasedYear ().
Tydzień pierwszy (1) to tydzień rozpoczynający się w getFirstDayOfWeek (), w którym jest co najmniej getMinimalDaysInFirstWeek () dni w roku. Tak więc pierwszy tydzień może rozpocząć się przed początkiem roku. Jeżeli pierwszy tydzień rozpoczyna się po rozpoczęciu roku, to poprzedni okres przypada w ostatnim tygodniu poprzedniego roku.
To pole może być używane z dowolnym systemem kalendarza.
W fazie rozstrzygania parsowania datę można utworzyć na podstawie tygodnia opartego na roku, tygodniu roku i dniu tygodnia.
W trybie ścisłym wszystkie trzy pola są sprawdzane pod kątem zakresu prawidłowych wartości. Pole tygodnia roku jest sprawdzane w celu upewnienia się, że wynikowy rok tygodniowy jest żądanym rokiem tygodniowym.
W trybie inteligentnym wszystkie trzy pola są sprawdzane pod kątem ich zakresu prawidłowych wartości. Pole roku opartego na tygodniu tygodnia jest sprawdzane w zakresie od 1 do 53, co oznacza, że wynikowa data może przypadać na kolejny rok tygodniowy do podanego.
W trybie łagodnym rok i dzień tygodnia są porównywane z zakresem prawidłowych wartości. Wynikowa data jest obliczana jako odpowiednik następującego trzystopniowego podejścia. Najpierw utwórz datę pierwszego dnia pierwszego tygodnia w żądanym roku tygodniowym. Następnie weź rok oparty na tygodniu tygodnia, odejmij jeden i dodaj kwotę w tygodniach do daty. Na koniec dostosuj się do prawidłowego dnia tygodnia w zlokalizowanym tygodniu.
Konfiguracja tej WeekFields
instancji zależy od lokalizacji i może mieć różne ustawienia w zależności od niej, kraje USA i Europy, takie jak Francja, mogą mieć inny dzień jako początek tygodnia.
Na przykład DateFormatterBuilder
Java 8, utwórz instancję parsera z ustawieniami narodowymi i użyj tych ustawień narodowych dla Y
symbolu:
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);
}
...
}
...
}
Oto przykład
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()));
A w odniesieniu do lokalizacji i wielkimi literami Y
, można grać z opcją wiersza poleceń -Duser.language=
( fr
, en
, es
, itd), lub wymusić ustawienia regionalne w czasie wywołania:
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)));