簡體   English   中英

Calendar 的 getActualMinimum 和 getGreatestMinimum 方法有什么區別?

[英]What's the difference between Calendar's getActualMinimum and getGreatestMinimum methods?

由於getActualMinimum()getGreatestMinimum()將為每個字段返回相同的值,那么究竟有什么區別呢?

getActualMinimum()方法返回屬性可能具有的最小可能值。 例如, Calendar.DAY_OF_MONTH永遠不會小於 1,因為沒有月份以 0 或更少的日期開始。

getGreatestMinimum()方法返回getActualMinimum()可能擁有的最大可能值。 雖然在大多數情況下這些值總是相同的(月份幾乎總是從 1 開始),但代碼允許它們在極少數情況下不同。 使用getGreatestMinimum()適用於數據驗證場景。

這可能(並且確實)發生的一個地方是日歷中存在跳過日期或不連續性的情況。 例如,Java 的GregorianCalendar實現了轉換日期之前的儒略歷和該日期之后的格里高利歷中的日期,因此有幾天的間隔,日歷中的日期根本不存在。

Calendar類的getGreatestMinimum()方法是抽象的,需要子類來實現。 JRE 對GregorianCalendar的實現表明,如果轉換月份的“跳過天數”不包括該月的第一天,則DAY_OF_MONTH字段可能會有所不同:

public int getGreatestMinimum(int field) {
    if (field == DAY_OF_MONTH) {
        BaseCalendar.Date d = getGregorianCutoverDate();
        long mon1 = getFixedDateMonth1(d, gregorianCutoverDate);
        d = getCalendarDate(mon1);
        return Math.max(MIN_VALUES[field], d.getDayOfMonth());
    }
    return MIN_VALUES[field];
}

以此作為提示,您可以使用setGregorianChange()設置儒略到格里高利更改的轉換日期。 默認情況下,它是 1582 年 10 月 15 日(從 1582 年 10 月 4 日起跳過了 10 天)。 不同的語言環境在不同的時間切換,例如英國在 1752 年 9 月 14 日(9 月 2 日之后的第二天)切換。

通過將此切換設置為一個月中的某個日期,使跳過的日期與該月的第一天重疊,我們可以生成這些邊緣情況。

具有實際切換日期的實際基於語言環境的不連續性可能是羅馬尼亞,其中 1919 年 3 月 31 日之后的第二天是 1919 年 4 月 14 日。因此,在羅馬尼亞語言環境中,1919 年 4 月將僅包括從 14 到 30 的天數,並且getGreatestMin()將返回 14。

由於我沒有安裝該語言環境,我可以更改轉換日期來模擬會發生什么:

GregorianCalendar cal = new GregorianCalendar();
// Deprecated, but an easy way of showing this example
cal.setGregorianChange(new Date(1911, Calendar.APRIL, 14));
System.out.println("actual min = " + cal.getActualMinimum(cal.DAY_OF_MONTH));
System.out.println("greatest min = " + cal.getGreatestMinimum(cal.DAY_OF_MONTH));

輸出:

actual min = 1
greatest min = 14

如果您使用Date(Long.MIN_VALUE)作為轉換,則存在另一個邊緣情況,提供沒有間隙的“純公歷”日歷。 但在這種情況下,“時間的開始”是當月的 16 日(在公歷中),所以在這種情況下最大的分鍾是 16。

其他日歷系統可能具有類似的不連續性和邊緣情況。

我建議您停止使用過時且容易出錯的java.util日期時間 API。 在現代日期時間 API 中, smallestMaximum是指最大值中的最小值,例如一個月的最大天數范圍從28 (對於Feb )到31 ,因此smallestMaximum28

類似的情況與名稱為自描述的largestMinimum的情況類似。 然而,不同於smallestMaximum其持有最大值范圍內的最小值,我一直沒能找到它的最大價值必須由舉辦最小值范圍largestMinimum 換句話說,通過保持的值minimumlargestMinimum是相同的所有ChronoField秒。

使用現代日期時間 API

import java.time.temporal.ChronoField;

public class Main {
    public static void main(String[] args) {
        // e.g. Value range for ChronoField.DAY_OF_MONTH
        System.out.println("Stats of ChronoField.DAY_OF_MONTH:");
        System.out.println("Supported value range: " + ChronoField.DAY_OF_MONTH.range());
        System.out.println("Maximum supported value: " + ChronoField.DAY_OF_MONTH.range().getMaximum());
        System.out.println("Minimum supported value: " + ChronoField.DAY_OF_MONTH.range().getMinimum());
        System.out.println("Largest minimum supported value: " + ChronoField.DAY_OF_MONTH.range().getLargestMinimum());
        System.out
                .println("Smallest maximum supported value: " + ChronoField.DAY_OF_MONTH.range().getSmallestMaximum());

        // e.g. Value range for ChronoField.DAY_OF_YEAR
        System.out.println("\nStats of ChronoField.DAY_OF_YEAR:");
        System.out.println("Supported value range: " + ChronoField.DAY_OF_YEAR.range());
        System.out.println("Maximum supported value: " + ChronoField.DAY_OF_YEAR.range().getMaximum());
        System.out.println("Minimum supported value: " + ChronoField.DAY_OF_YEAR.range().getMinimum());
        System.out.println("Largest minimum supported value: " + ChronoField.DAY_OF_YEAR.range().getLargestMinimum());
        System.out.println("Smallest maximum supported value: " + ChronoField.DAY_OF_YEAR.range().getSmallestMaximum());
    }
}

輸出:

Stats of ChronoField.DAY_OF_MONTH:
Supported value range: 1 - 28/31
Maximum supported value: 31
Minimum supported value: 1
Largest minimum supported value: 1
Smallest maximum supported value: 28

Stats of ChronoField.DAY_OF_YEAR:
Supported value range: 1 - 365/366
Maximum supported value: 366
Minimum supported value: 1
Largest minimum supported value: 1
Smallest maximum supported value: 365

檢查TemporalAccessor#range以獲取更多詳細信息。 Trail: Date Time 中了解有關現代日期時間 API 的更多信息。

沒有像 leastminimum 這樣的方法。 方法是 getActualMaximum()、getActualMinimum()、getLeastMaximum()、getMaximum() 和 getMinimum()

getLeastMaximum() 將返回 28,getMaximum() 將返回 31,getMinimum() 將返回 1 作為輸入作為 Calendar.DAY_OF_WEEK

帶有“實際”的方法將返回特定於正在使用的日歷實例值的相應最小值或最大值。 (有些日歷一年有 13 個月)

所以實際值是相對的,其他 3 種方法是絕對的。

我只是通讀了 java doc 和下面的 2 個鏈接來得出這個結論

getActualMaximum()

getActualMinimum()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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