JodaTime中的最小/最大日期/日期时间

在JodaTime中有没有办法构造一个Date / DateTime,它总是比任何其他Date / DateTime更小/更大? 有点像

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

约束:我不想使用标准的Java Date库。

java.time

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

对于java.time中的min / max,请参阅我对类似问题的回答 。

乔达时间

Joda-Time将时间跟踪自UTC 1970年第一时刻以来的毫秒数。 此计数使用64位 long整数保持。 因此,从技术上讲,最大值和最小值是长度的+/-限制。

 … new DateTime( Long.MIN_VALUE ) … new DateTime( Long.MAX_VALUE ) 

Joda-Time没有这样的最小/最大值可以方便地作为常数。 相比之下,请注意Joda-Time的后续版本java.time内置于Java 8及更高版本中确实提供了常量LocalDateTime.MINLocalDateTime.MAX

顺便说一句,Joda-Time团队建议我们应该迁移到java.time。 大部分java.timefunction都被反向移植到ThreeTen-Backport中的Java 6和7,进一步适用于ThreeTen-ABP中的 Android。

太大,太小

要小心这些极端。 它们的使用并不实用。 各种库,应用程序,数据库和其他日期时间值的汇/源可能具有很多不同的限制,一些更大但通常更小。

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

另一个限制是表单和报表上字段的物理显示大小,每年只需要四位数字。

解决方法

您可以定义自己的最小/最大值。

您可能需要极端值,例如0000年和9999年.Joda-Time支持的时间晚于9,999,但我会坚持使用4位数来适应屏幕和报告中常用的格式。 在视觉上,这四个九是一个虚假的日子。

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

我建议在辅助类上定义常量。 像这样的东西:

 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( "END_OF_TIME: " + 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 

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

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

Years.MAX_VALUE.getYears()我有以下exception:

在此处输入图像描述

因此,使用从例外的最大年数,我得出了以下宇宙结束日期时间:

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

有关详细信息,请参阅文档
这里也可以阅读一个有趣的讨论。

在阅读了很多不同的切线之后,我最终决定找出适用于UTC时区最小值和最大值的最小情况。 事实certificate,尝试使用LongMIN_VALUEMAX_VALUE我失去兔子踪迹。

因此,给出以下代码段:

 new DateTime(milliseconds, DateTimeZone.UTC) 

以下是工作milliseconds的最小/最大值(在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亿。