为什么将Java.Time.Year任意限制为小于其原始限制?

时间:2018-12-11 20:17:29

标签: java time limit

Java.Time.Year的Java 8文档页面指出支持的最小和最大年份分别为-999,999,999和999,999,999。

  

字段摘要

     

static int MAX_VALUE支持的最大年份为“ +999,999,999”。

     

static int MIN_VALUE支持的最低年份为“ -999,999,999”。


但是,存储年份值的原始类型变量是 int ,它应该能够存储-2,147,483,648和2,147,483,647之间。

/**
 * The year being represented.
 */
private final int year;

为什么会有这些任意限制?

1 个答案:

答案 0 :(得分:6)

使用999,999,999的原因未与代码中解析实现的任何特定问题相关联。

它很可能已被选择,因为它是由1到9位数字组成的任何数字的最大值。我们无法使用INT存储完整的年份到10位数字,因为9,999,999,999(坦率地说,可能的10位数字中的另外79%)不能存储为整数。重要的是要注意,格式化程序本身可以无缝支持高达64位的单个数字,并且仅使用MIN / MAX进行错误检查。如果将最小值/最大值提高到INT_MIN和INT_MAX,它仍然可以正常工作。超过INT_MAX的值将正确地引发错误并防止任何有关整数溢出的问题,因此无需担心任何解析失败。

    ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
            .appendLiteral('-')
            .appendValue(MONTH_OF_YEAR, 2)
            .appendLiteral('-')
            .appendValue(DAY_OF_MONTH, 2)
            .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);

对于传统的ISO,年份是4个数字,即0-9999;对于999999年,年份是+/-,即+999999。

值得注意的是,ISO_LOCAL_DATE格式化程序默认接受10位数字的年份,但不包括+/-号,因此+9,876,543,210的值实际上已正确解析,但超过了MAX_YEAR的可接受值。

Text '+9876543210-10-31' could not be parsed: Invalid value for Year (valid values -999999999 - 999999999): 9876543210

DateTimeFormatterBuilder中的所有内容最多支持64位数字,一次解析一个数字。所有这些值都被安全地解析为BigIntegers,并在索引向右移动时小心地乘以10,并在完成后将其转换并存储在由字段名称和long组成的解析上下文中,即使可以清楚地存储字段Months和Days作为INTS。稍后将它们转换回其关联的基元。

实际上,DateTimeFormatterBuilder可以肯定地将2,147,483,647用作有效的最小/最大年份。

实际上,“ Java接受不超过9位数字的任何年份的值”的描述提出了一个具体的障碍,即相加两年时,整数整数的溢出或混淆的可能性不大,并且减少了关于为什么21亿年有效,但是22亿年停顿了。