Đây là hai lĩnh vực trong gói java.time.temporal
:Động lực cho hai định nghĩa dựa trên tuần khác nhau trong JSR-310 là gì?
WeekFields.ISO.weekBasedYear()
tiêu chuẩn ISO-8601 định nghĩa một ngày trong tuần cái gọi là bên cạnh hai loại khác trong ngày, cụ thể là ngày lịch thông thường (bao gồm năm, tháng và ngày trong tháng) và ngày thứ tự (bao gồm năm và ngày trong năm). Một weekdate được định nghĩa theo định dạng YYYY-'W'ww-e. w là viết tắt của tuần-của-năm, e cho số ISO-ngày-trong tuần. Y là viết tắt của tuần dựa trên năm và là giống hệt với năm dương lịch với ngoại lệ vào đầu hoặc cuối năm dương lịch, bởi vì một tuần dựa trên năm là ràng buộc với chu kỳ tuần mà cuối cùng có thể bắt đầu trong năm trước. Hai quy tắc quan trọng để hiểu cách một ngày trong tuần được hình thành:
- Tuần luôn bắt đầu vào thứ Hai.
- Tuần đầu tiên của năm dương lịch là tuần có chứa ít nhất bốn ngày.
Thoạt nhìn, cả hai trường JSR-310 có vẻ giống nhau vì ISO-8601 chỉ đề cập đến một loại dựa trên tuần. Nhưng chờ đợi, bất ngờ. Chúng ta hãy xem xét sau mã ví dụ:
LocalDate date1 =
LocalDate.of(2000, 2, 29).with(IsoFields.WEEK_BASED_YEAR, 2014);
System.out.println("IsoFields-Test: " + date1); // output: 2014-03-01
LocalDate date2 =
LocalDate.of(2000, 2, 29).with(WeekFields.ISO.weekBasedYear(), 2014);
System.out.println("WeekFields-Test: " + date2); // output: 2014-02-25
Trong khi tôi rất tốt hiểu sự thay đổi thứ hai tôi thực sự ngạc nhiên khi thấy kết quả khác nhau cho ngày đầu tiên được sử dụng "chính thức" tiêu chuẩn ISO-8601-tài liệu tham khảo trong classname của nó. Để giải thích các kết quả tính toán:
Ngày 2000-02-29 tương ứng với 2000-W09-2 trong ký hiệu ISO-weekdate trong khi 2014-02-25 tương ứng với 2014-W09-2 giữ nguyên tuần-of- năm và ngày trong tuần. Cho đến nay rất tốt. Đặc điểm bảo quản này cho các trường nhỏ hơn tương tự như quy tắc cách thay đổi năm dương lịch (trong hầu hết các trường hợp, nên giữ tháng và ngày trong tháng không thay đổi).
Nhưng kết quả là gì 2014-03-01? Ở đây thuật toán chỉ đơn giản là thêm bốn ngày vào ngày tuần tương ứng để tính đến sự khác biệt trong trường "ngày-tháng" (29 so với 25). Tôi chưa tìm thấy bất kỳ nguồn tài liệu hoặc tài liệu chính thức nào cho hành vi này. Có ai biết nơi chúng ta có thể tìm thấy sự biện minh cho sự khác biệt giữa hai lĩnh vực này? Bất kỳ tài liệu nào có sẵn về hành vi thuật toán?
UPDATE:
Bây giờ tôi cố gắng để kiểm tra tự nhất quán của API mới với biểu hiện này để tìm hiểu nào trong hai lĩnh vực được hỗ trợ tốt hơn:
System.out.println(
"14 week-based-years later = "
+ LocalDate.of(2000, 2, 29).plus(14, IsoFields.WEEK_BASED_YEARS));
Các đầu ra là 2014-03-01 tương tự như trường hợp được mô tả là IsoFields.WEEK_BASED_YEAR
, mặc dù tôi vẫn tìm thấy kết quả 2014-02-25 (= 2014-W09-2) hợp lý hơn nhiều. Vì đơn vị thời gian này cũng được tìm thấy trong lớp IsoFields
cho đến nay hành vi này là tự nhất quán trong lớp IsoFields
. Có vẻ như một tính năng "không có giấy tờ và không trực quan".
Tôi đang sử dụng phiên bản: java.runtime.version = 1.8.0-b132
Nhiều thử nghiệm:
LocalDate d = LocalDate.of(2014, 3, 1); // 2014-W09-6
System.out.println(
"week-of-year in 2014-03-01: "
+ d.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
System.out.println(
"day-of-week in 2014-03-01: "
+ d.get(ChronoField.DAY_OF_WEEK));
LocalDate later = d.plus(14, IsoFields.WEEK_BASED_YEARS); // 2028-03-02 = 2028-W09-4
System.out.println(
"14 week-based-years later = "
+ later);
System.out.println(
"week-of-year in " + later + ": "
+ later.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
System.out.println(
"day-of-week in " + later + ": "
+ later.get(ChronoField.DAY_OF_WEEK));
Output:
week-of-year in 2014-03-01: 9
day-of-week in 2014-03-01: 6
14 week-based-years later = 2028-03-02
week-of-year in 2028-03-02: 9
day-of-week in 2028-03-02: 4
tôi không nhận ra bất kỳ quy tắc rõ ràng. Cả ngày trong tuần được bảo tồn cũng như ngày trong tháng được bảo tồn trong khi thêm 14 tuần dựa trên năm. Vì vậy, đây là một câu hỏi phụ: Quy tắc đằng sau IsoFields.WEEK_BASED_YEARS
là gì? Có lẽ JSR-310-team có thể khai sáng cho chúng tôi?
Nếu bạn tìm thấy lỗi, tôi khuyên bạn nên gửi báo cáo lỗi. – assylias
@assylias cảm ơn gợi ý, về quy tắc cho đơn vị dựa trên tuần có vẻ như là một lỗi, cho câu hỏi đầu tiên tôi không chắc chắn nếu JSR-310-đội đủ điều kiện nó như là lỗi hoặc tính năng. –
2014-W09-6 + 14 tuần nên sản xuất 2028-W09-6, bất kỳ điều gì khác là lỗi! Bạn sẽ không chấp nhận 2014-03-01 + 14 năm dương lịch để sản xuất mọi thứ trừ 2028-03-01, phải không? – chansen