簡體   English   中英

Java 日歷 DAY_OF_WEEK 設置為零

[英]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.SUNDAYCalendar.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.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM