[英]Java Calendar DAY_OF_WEEK SET to zero
我有這個來自 PROD(> 7 年)的非常舊的代碼塊要調試。 有一點我無法理解。 代碼中的一部分會計算下一次任務將運行的時間,對於需要在星期天(星期一)專門運行的任務,它使用 Calendar.SUNDAY。 但是有一個陳述,即使在多次閱讀文檔后我也無法解釋其行為
日歷 cal = Calendar.getInstance(); cal.set(Calendar.DAY_OF_WEEK, 0);
因為天數從 1-7 ( Calendar.SUNDAY
到Calendar.SATURDAY
)可以解釋,但零在這里如何工作,為什么沒有例外?
為什么沒有例外?
這是因為您沒有將寬松模式設置為false
,默認情況下為true
。
演示:
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.set(Calendar.DAY_OF_WEEK, 0);
System.out.println(cal.getTime());
}
}
Output:
Exception in thread "main" java.lang.IllegalArgumentException: DAY_OF_WEEK
文檔說:
任何超出范圍的值要么在寬松模式下標准化,要么在非寬松模式下被檢測為無效值
作為規范化的一部分,該值會翻轉,例如以下代碼將值設置為等效於cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY - 1)
:
cal.set(Calendar.DAY_OF_WEEK, 0);
同樣,以下代碼將值設置為相當於cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY - 2)
:
cal.set(Calendar.DAY_OF_WEEK, -1);
通過在“測試台”中嘗試,我發現了這一點:
當數字 1-7 “溢出”時,它看起來是“日歷集”調整值/整數。 我可以看到這種模式:
Day Of Week: 1 2 3 4 5 6 7 | 1 2 3 4 5 6 7 | 1 2 3 4 5 6 7 | ...
Value of calendar: -6 -5 -4 -3 -2 -1 0 | 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 | ...
試驗台:
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_WEEK, -6);
System.out.println("Calendar value -6 returns: " + cal.get(Calendar.DAY_OF_WEEK));
cal.set(Calendar.DAY_OF_WEEK, 0);
System.out.println("Calendar value 0 returns: " + cal.get(Calendar.DAY_OF_WEEK));
cal.set(Calendar.DAY_OF_WEEK, 1);
System.out.println("Calendar value 1 returns: " + cal.get(Calendar.DAY_OF_WEEK));
cal.set(Calendar.DAY_OF_WEEK, 7);
System.out.println("Calendar value 7 returns: " + cal.get(Calendar.DAY_OF_WEEK));
cal.set(Calendar.DAY_OF_WEEK, 8);
System.out.println("Calendar value 8 returns: " + cal.get(Calendar.DAY_OF_WEEK));
cal.set(Calendar.DAY_OF_WEEK, 14);
System.out.println("Calendar value 14 returns: " + cal.get(Calendar.DAY_OF_WEEK));
}
Output:
Calendar value -6 returns: 1
Calendar value 0 returns: 7
Calendar value 1 returns: 1
Calendar value 7 returns: 7
Calendar value 8 returns: 1
Calendar value 14 returns: 7
Output 是根據“模式”。
我建議您使用 java.time,現代 Java 日期和時間 API,用於您的日期和時間工作。 例如:
LocalDate ld = LocalDate.now(ZoneId.systemDefault())
.with(DayOfWeek.TUESDAY);
System.out.println(ld);
今天,6 月 5 日星期六,當我運行此代碼時,output 是:
2021-06-01
是的,6 月 1 日是星期二。 由於我們將枚舉常量傳遞給with()
,因此實際上不可能傳遞超出范圍的值。 DayOfWeek
是一個枚舉,在一周的 7 天中包含 7 個值。 我們唯一能遇到的麻煩是通過null
,這將拋出NullPointerException
,我認為你想要。
但是,如果我們確實堅持將星期幾作為數字傳遞,那是可能的。 java.time 編號從星期一 = 1 到星期日 = 7 的星期幾。
LocalDate ld = LocalDate.now(ZoneId.systemDefault())
.with(ChronoField.DAY_OF_WEEK, 2);
到目前為止,output 和以前一樣是2021-06-01
。 但是如果我們通過 0 呢?
.with(ChronoField.DAY_OF_WEEK, 0);
線程“主”java.time.DateTimeException 中的異常:DayOfWeek 的值無效(有效值 1 - 7):0
我們不僅會收到您要求的例外情況,而且還會收到明確且有用的例外信息,恕我直言。
使用Calendar
星期 0 的工作方式與 7 = 星期六相同。 似乎至少有一個寬松的老式GregorianCalendar
在星期幾執行一種模 7 運算,以將其置於 1 到 7 的區間內。我沒有發現這個記錄。 GregorianCalendar
可能是您正在處理的Calendar
的具體子類。 我嘗試了不同的數字,它們都等於 7 模 7:
int[] dows = { 0, 7, -7, 14, -14, -98 };
for (int dow : dows) {
Calendar cal = new GregorianCalendar(2021, Calendar.JUNE, 2);
Date dateBefore = cal.getTime();
cal.set(Calendar.DAY_OF_WEEK, dow);
System.out.format("%s and day of week %3d yields %s%n", dateBefore, dow, cal.getTime());
}
Output:
Wed Jun 02 00:00:00 CEST 2021 and day of week 0 yields Sat Jun 05 00:00:00 CEST 2021 Wed Jun 02 00:00:00 CEST 2021 and day of week 7 yields Sat Jun 05 00:00:00 CEST 2021 Wed Jun 02 00:00:00 CEST 2021 and day of week -7 yields Sat Jun 05 00:00:00 CEST 2021 Wed Jun 02 00:00:00 CEST 2021 and day of week 14 yields Sat Jun 05 00:00:00 CEST 2021 Wed Jun 02 00:00:00 CEST 2021 and day of week -14 yields Sat Jun 05 00:00:00 CEST 2021 Wed Jun 02 00:00:00 CEST 2021 and day of week -98 yields Sat Jun 05 00:00:00 CEST 2021
Oracle 教程:日期時間解釋如何使用 java.time。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.