[英]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
,因此smallestMaximum
是28
。
類似的情況與名稱為自描述的largestMinimum
的情況類似。 然而,不同於smallestMaximum
其持有最大值范圍內的最小值,我一直沒能找到它的最大價值必須由舉辦最小值范圍largestMinimum
。 換句話說,通過保持的值minimum
和largestMinimum
是相同的所有ChronoField
秒。
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 個鏈接來得出這個結論
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.