Min/Max Date/DateTime 在 jodatime 中

Min/Max Date/DateTime in JodaTime

在 JodaTime 中有没有什么方法可以构建一个 Date/DateTime,它总是比任何其他 Date/DateTime 都 smaller/larger?类似于

DateTime bigBang = DateTime.xxx();
DateTime endOfUniverse = DateTime.yyy();

约束:我不想使用标准 Java 日期库。

当所有日期都在同一时区内时,您可以创建 DateTime 对象,并将字段分配给最小值或最大值。
但是当使用这个构造函数时

DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute)

with Years.MAX_VALUE.getYears() 我有以下例外:

因此,使用异常后的最大年数,我得出了以下宇宙末日日期时间:

DateTime dtMax = new DateTime(292278993, 12, 31, 23, 59, 59);
System.out.println(dtMax);
// prints 292278993-12-31T23:59:59

有关详细信息,请参阅 documentation
也可以阅读有趣的讨论 here.

java.time

Joda-Time 项目现在处于维护模式。该团队建议迁移到 java.time classes.

对于 java.time 中的 min/max,请参阅 my Answer 的类似问题。

乔达时间

Joda-Time tracks time as a count of milliseconds since the epoch of first moment of 1970 in UTC. This count is kept using a 64-bit long 整数。因此,从技术上讲,最大值和最小值是 long.

的 +/- 限制
… new DateTime( Long.MIN_VALUE )
… new DateTime( Long.MAX_VALUE )

Joda-Time 没有这样的 minimum/maximum 值可以方便地用作常量。相比之下,请注意 Joda-Time 的继任者 java.time built into Java 8 and later, does indeed offer the constants LocalDateTime.MIN and LocalDateTime.MAX.

顺便说一下,Joda-Time 团队建议我们应该迁移到 java.time。 java.time 的大部分功能都反向移植到 ThreeTen-Backport, further adapted to Android in ThreeTen-ABP.

中的 Java 6 & 7

太大,太小

当心这些极端情况。它们的使用并不实用。各种库、应用程序、数据库和其他 sinks/sources 日期时间值的限制可能有很大不同,有些要大得多,但通常要小得多。

例如,许多系统使用 UNIX 的古老传统和 POSIX 跟踪时间作为自 1970-01-01T00:00:00Z 以来整秒的 32 位整数计数。 +/- 20 亿秒的自然极限导致 Year 2038 Problem 迫在眉睫。

另一个限制是表格和报告中字段的物理显示大小,要求年份数字中只有四位数字。

解决方法

您可以定义自己的 min/max。

您可能需要极端值,例如 0000 年和 9999 年。Joda-Time 支持晚于 9,999 的年份,但我会坚持使用 4 位数字以适应屏幕和报告中显示的常用格式。从视觉上看,四个九是假日期。

或者您可能需要适合您的业务逻辑的预期最小值。如果建立一个新的发票系统,那么你知道年份应该总是今年或更晚。

我建议在助手上定义常量 class。像这样:

package com.example;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class JodaTimeHelper {

    static final public DateTime START_OF_TIME = new DateTime( 0000, 1, 1, 0, 0, 0, DateTimeZone.UTC );
    static final public DateTime END_OF_TIME = new DateTime( 9999, 1, 1, 0, 0, 0, DateTimeZone.UTC );

    static final public DateTime MINIMUM_INVOICE_DATETIME = new DateTime( 2015, 1, 1, 0, 0, 0, DateTimeZone.UTC );

}

调用这些常量的语法如下。

System.out.println( "START_OF_TIME: " + JodaTimeHelper.START_OF_TIME );
System.out.println( "END_OF_TIME: " + JodaTimeHelper.END_OF_TIME );
System.out.println( "MINIMUM_INVOICE_DATETIME: " + JodaTimeHelper. MINIMUM_INVOICE_DATETIME );

当运行.

START_OF_TIME: 0000-01-01T00:00:00.000Z
END_OF_TIME: 9999-01-01T00:00:00.000Z
MINIMUM_INVOICE_DATETIME: 2015-01-01T00:00:00.000Z

在阅读了很多不同的切线之后,我最终决定找出一个适用于 UTC 时区的最小值和最大值的最小案例。事实证明,尝试使用 LongMIN_VALUEMAX_VALUE 会让我走上兔子之路。

因此,给定以下代码片段:

new DateTime(milliseconds, DateTimeZone.UTC)

这里是适用于 milliseconds 的 minimum/maximum 值(在 Java 1.7 中测试):

UTC_DATE_TIME_MIN_VALUE_IN_MILLIS = 9223372017129599999L
UTC_DATE_TIME_MAX_VALUE_IN_MILLIS = -9223372017043200000L

这两个值都与Long.MIN_VALUELong.MAX_Value相差约200亿。