Java是否足够长以以毫秒为单位存储纪元时间?

时间:2019-02-01 00:17:10

标签: java timestamp long-integer epoch

我可以使用Java long来以合理的精度存储历元时间(以微秒为单位),而没有任何特殊的有符号到无符号转换技巧吗?如果可以,我将如何计算结束日期范围?

这是通常的8个字节的日期范围: -9,223,372,036,854,775,808至9,223,372,036,854,775,807

更新

使用建议:

lst = ['object1','object2','object3']

这是um的结束日期:

['1','2','3']

这是结束时间,使用正的长值表示纳秒:

new Date(Long.MAX_VALUE)

1 个答案:

答案 0 :(得分:4)

tl; dr

    纳诺斯只给了三个世纪。
  • 切勿自行计时。 ☛使用java.time
  • 交换日期时间值时,切勿使用从纪元开始计数,而应使用标准ISO 8601格式的文本。

做数学

您必须选择一个epoch reference date。尽管dozens of various epochs在行业中使用,但更常见的一种通常称为Unix Time:UTC 1970年的第一时刻,1970-01-01T00:00:00Z。使用正数计数来跟踪该点之后的时刻,而使用负数计数来跟踪之前的时刻。

当然,一年的长度因Le年而异,但我们可以很容易地得出近似值。使用TimeUnit类及其便捷的转换方法来获取一年中的nanoseconds数。

输入一些数字。

long nanosPerDay = TimeUnit.DAYS.toNanos( 1L );
long nanosPerYear = ( long ) ( nanosPerDay * 365.25 );
long maximumYears = ( Long.MAX_VALUE / nanosPerYear );

转储到控制台。

System.out.println( "nanosPerDay: " + nanosPerDay );
System.out.println( "nanosPerYear: " + nanosPerYear );
System.out.println( "Long.MAX_VALUE: " + Long.MAX_VALUE + " provides for maximumYears: " + maximumYears );

请参阅此code run live at IdeOne.com

  

nanosPerDay:86400000000000

     

nanos每年:31557600000000000

     

Long.MAX_VALUE:9223372036854775807规定了最长年份:292

因此,在1970年之前和之后,我们得到的收益少于±3个世纪。因此,只要几个世纪的时间对您的应用程序来说足够好,这种方法就行得通。日历用完后,至少您不会来修复它。 ;-)

Instant

幸运的是,我们不需要自己做这个数学运算。

现代Java恰好带有面向业务的应用程序可用的最先进的日期时间处理框架:在JSR 310中定义的 java.time 类。

java.time.Instant类使用其他策略来跟踪时间。该类在1970 UTC时代之前/之后保持整个秒的计数,并在瞬间的小数秒内加上单独的纳秒计数。

认为是:

moment = ( whole-seconds + fractional-second ) ; // Since 1970-01-01T00:00:00Z.

这使最小值/最大值为:

请注意, java.time 类确实具有纳秒级的分辨率,而它们所取代的旧类(DateCalendar等)解析为{{3 }}。

有关详细信息,请参见milliseconds和OpenJDK class JavaDoc(在source code中)。

提示: java.time 类最适合面向业务的目的。如果您从事科学,工程,考古或历史工作,请使用其他适合该领域的符号,可能是String类型。

粒度

请注意,不同的计算机系统在计时方面使用不同的粒度。

如上所述, java.time 类解析为纳秒,即十进制小数点后九位。传统类使用毫秒,即十进制小数点后三位数字。其他系统(例如Mercurial数据库)将Postgres用作十进制小数秒的六位数。在跨系统交换或比较数据时,您可能想在各种 java.time 类上使用truncatedTo方法。

当前的常规计算机硬件时钟仅精确到微秒或更粗。它们可能以纳秒为单位报告,但达不到该程度的准确度。因此,您会发现Java 9、10和11中的Instant.now()方法将当前时刻捕获到了微秒(虽然数据类型可以 handle nanos,但它检测到当前时间(以毫秒为单位)。

  

Instant.now()。toString():2019-01-23T12:34:56.123456Z


关于 java.time

microseconds框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧java.time日期时间类,例如legacyjava.util.DateCalendar

目前位于SimpleDateFormatJoda-Time项目建议迁移到maintenance mode类。

要了解更多信息,请参见java.time。并在Stack Overflow中搜索许多示例和说明。规格为Oracle Tutorial

您可以直接与数据库交换 java.time 对象。使用符合JSR 310或更高版本的JDBC driver。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

How to use ThreeTenABP…项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如ThreeTen-ExtraIntervalYearWeekYearQuarter