既然getActualMinimum()
并且getGreatestMinimum()
将为每个字段返回相同的值,那么确切的区别是什么?
3 回答
该getActualMinimum()
方法返回属性可能具有的最小可能值。例如,Calendar.DAY_OF_MONTH
永远不会小于 1,因为没有月份以编号为 0 或更少的日期开始。
该getGreatestMinimum()
方法返回可能具有的最大可能值getActualMinimum()
。虽然在大多数情况下这些值总是相同的(月份几乎总是从 1 开始),但代码允许它们在极少数情况下不同。使用getGreatestMinimum()
适用于数据验证场景。
这可能(并且确实)发生的一个地方是日历中存在跳过的日期或不连续的情况。例如, JavaGregorianCalendar
实现了转换日期之前的儒略历中的日期,以及该日期之后的公历,因此在日历中的日期根本不存在的地方有几天的间隙。
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
(for Feb
) 到31
因此smallestMaximum
是28
。
largestMinimum
其名称具有自我描述性的情况也是如此。但是,与在最大值范围内smallestMaximum
保持最小值不同的是,我无法找到最小值范围,其中最大值必须由. 换句话说,所有 s 所持有的值和都是相同的。largestMinimum
minimum
largestMinimum
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 的更多信息。
没有像 minimumminimum 这样的方法。方法是 getActualMaximum()、getActualMinimum()、getLeastMaximum()、getMaximum() 和 getMinimum()
getLeastMaximum() 将返回 28,getMaximum() 将返回 31,getMinimum() 将返回 1 作为 Calendar.DAY_OF_WEEK 的输入
具有“实际”的方法将返回特定于正在使用的日历实例值的相应最小值或最大值。(有些日历一年有13个月)
所以实际值是相对的,其他 3 种方法是绝对的。
我刚刚通读了 java doc 和下面的 2 个链接,得出了这个结论