Đây là bản cập nhật Java 8 với một số mã, vì GregorianCalendar có thể sẽ không được chấp nhận hoặc bị xóa khỏi các phiên bản JDK trong tương lai.
Mã mới được xử lý trong WeekFields
lớp và cụ thể cho chữ thường y
/ chữ hoa Y
với bộ truy cập weekBasedYear()
trường.
Trả về một trường để truy cập năm của năm dựa trên tuần dựa trên Trường trong tuần này. Điều này thể hiện khái niệm về năm mà các tuần bắt đầu vào một ngày cố định trong tuần, chẳng hạn như Thứ Hai và mỗi tuần thuộc đúng một năm. Trường này thường được sử dụng với dayOfWeek () và weekOfWeekBasedYear ().
Tuần một (1) là tuần bắt đầu trên getFirstDayOfWeek (), nơi có ít nhất getMinimalDaysInFirstWeek () ngày trong năm. Do đó, tuần đầu tiên có thể bắt đầu trước khi bắt đầu năm. Nếu tuần đầu tiên bắt đầu sau ngày bắt đầu của năm thì khoảng thời gian trước đó là vào tuần cuối cùng của năm trước.
Trường này có thể được sử dụng với bất kỳ hệ thống lịch nào.
Trong giai đoạn phân tích cú pháp phân tích cú pháp, một ngày có thể được tạo từ tuần dựa trên năm, tuần trong năm và ngày trong tuần.
Ở chế độ nghiêm ngặt, cả ba trường đều được xác thực theo phạm vi giá trị hợp lệ của chúng. Trường tuần trong năm được xác thực để đảm bảo rằng năm dựa trên tuần kết quả là năm dựa trên tuần được yêu cầu.
Ở chế độ thông minh, cả ba trường đều được xác thực dựa trên phạm vi giá trị hợp lệ của chúng. Trường theo tuần dựa trên năm được xác thực từ 1 đến 53, có nghĩa là ngày kết quả có thể nằm trong năm dựa trên tuần tiếp theo so với năm được chỉ định.
Trong chế độ khoan dung, năm và ngày trong tuần được xác thực theo phạm vi giá trị hợp lệ. Ngày kết quả được tính tương đương với cách tiếp cận ba giai đoạn sau. Trước tiên, hãy tạo một ngày vào ngày đầu tiên của tuần đầu tiên trong năm dựa trên tuần được yêu cầu. Sau đó, lấy tuần của tuần dựa trên năm, trừ đi một và cộng số tuần vào ngày. Cuối cùng, điều chỉnh cho đúng ngày trong tuần trong tuần được bản địa hóa.
Việc thiết lập cái này WeekFields
phụ thuộc vào ngôn ngữ và có thể có các cài đặt khác nhau tùy thuộc vào nó, các quốc gia Hoa Kỳ và Châu Âu như Pháp có thể có một ngày khác kể từ đầu tuần.
Ví dụ DateFormatterBuilder
về Java 8, khởi tạo trình phân tích cú pháp với ngôn ngữ và sử dụng ngôn ngữ này cho Y
ký hiệu:
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);
}
...
}
...
}
Đây là một số ví dụ
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()));
Và về vấn đề của địa phương và các trường hợp trên Y
, bạn có thể chơi với các tùy chọn dòng lệnh -Duser.language=
( fr
, en
, es
, vv), hoặc buộc các miền địa phương vào thời điểm gọi:
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)));