因此,我们的数据库中有一列BigInt REVISIONTS用作Java Hibernate Envers的一部分
最初包含来自Java Date的时间戳。
例如,ts=1561637560383
我曾经使用new Date(ts)
但是由于Date不能包含时区,而且我们需要UTC日期,因此我们不得不将UTC直接存储为BigInt并应用了休眠建议的修复程序。因此,我们的时间戳就是这样
例如,ts=20190827202449
现在不再是时间戳,而是存储为bigint的实际UTC LocaleDateTime
现在查询此内容会很长,如果我使用new Date(ts)
,我当然会得到错误的日期,因为这不是时间戳,而是带有Temporal的休眠日期。时间戳按原样存储UTC。
我正在考虑将Long转换为字符串,并在检索时使用格式化将其转换回。
还有其他更清洁的转换方法吗?
适用于Envers的UTC修复程序
How to save UTC (instead of local) timestamps for Hibernate Envers revision info?
答案 0 :(得分:3)
您根本不应该使用Date
。决不。曾经。
我认为将时间存储为Unix时间戳很好。它们始终使用UTC,并且在时间轴上代表唯一的时刻。
Envers支持将Date
和Long
/ long
定义为修订时间戳。您应该使用Long
。
使用java.time
软件包中提供的更新的Java Date and Time API,可以轻松地使用时区或时区偏移量对其进行格式化。
使用Instant.ofEpochSecond(yourTimestamp)
,您可以创建一个Instant
。使用atOffset
或atZone
,您可以将裸时间戳与特定时区或时区偏移量结合使用。
答案 1 :(得分:3)
您的问题还不清楚。但这可能会有帮助。
使用新的日期(ts)转换为日期
请勿使用java.util.Date
。几年前,那个可怕的类被 java.time 类取代,特别是被Instant
取代。
Instant
例如ts = 1561637560383
您不清楚该值代表什么。我猜这是从1970年1月19日UTC 1970-01-01T00:00Z的纪元参考开始算起的毫秒数。
long count = 1_561_637_560_383L ;
如果这是文本值,请使用Long
类进行解析。
long count = Long.parseLong( "1561637560383" ) ;
Instant instant = Instant.ofEpochMilli( count ) ;
请参阅此code run live at IdeOne.com。
instant.toString():2019-06-27T12:12:40.383Z
提示:在数据库中,使用日期时间数据类型存储日期时间值。
如果您的数据库太原始了,不支持日期时间类型,请使用ISO 8601格式以文本形式存储在UTC中。
String output = instant.toString() ; // Ex: 2019-06-27T12:12:40.383Z
…和…
Instant instant = Instant.parse( "2019-06-27T12:12:40.383Z" ) ;
获取自纪元引用以来的毫秒数。
long count = instant.toEpochMilli() ;
当您必须使用Date
与尚未更新为 java.time 的旧代码进行互操作时,请进行转换。调用添加到旧类中的新to…
/ from…
方法。
java.util.Date d = Date.from( instant ) ;
Instant instant = d.toInstant() ;