如何将Google原始时间戳转换为Java LocalDate?

Thi*_*asu 5 java date proto grpc grpc-java

我们需要将Google Proto缓冲时间戳转换为正常日期。在这种情况下,是否可以将Google Proto缓冲区时间戳LocalDate直接转换为Java ?

Bas*_*que 6

tl; dr

作为UTC的片刻,请转换为java.time.Instant。然后应用时区以获取ZonedDateTime。将仅日期部分提取为LocalDate

单线:

Instant
.ofEpochSecond( ts.getSeconds() , ts.getNanos() ) 
.atZone( ZoneId.of( "America/Montreal" ) ) 
.toLocalDate() 
Run Code Online (Sandbox Code Playgroud)

兑换

第一步是将Timestamp对象的秒数和小数秒(纳秒)转换为java.time类。具体来说,java.time.Instant。就像一样TimestampInstant代表UTC中具有纳秒分辨率的时刻。

Instant instant =  Instant.ofEpochSecond( ts.getSeconds() , ts.getNanos() ) ;
Run Code Online (Sandbox Code Playgroud)

确定日期需要一个时区。在任何给定时刻,日期都会在全球范围内变化。

将应用于ZoneId我们Instant得到一个ZonedDateTime。同一时刻,时间轴上的同一点,不同的时钟时间。

ZoneId z = ZoneId( "Pacific/Auckland" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;
Run Code Online (Sandbox Code Playgroud)

将仅日期部分提取为LocalDate。A LocalDate没有时间,也没有时区。

LocalDate ld = zdt.toLocalDate() ;
Run Code Online (Sandbox Code Playgroud)

注意:不要使用LocalDateTime类用于此目的,在另一个答案不幸所示。该类故意缺少时区或从UTC偏移的任何概念。因此,它不能代表一个时刻,也不是时间轴上的一点。请参阅课程文档。

兑换

最好完全避免包括非常麻烦的传统日期时间类DateCalendarSimpleDateFormat。但是,如果必须与尚未更新为java.time的旧代码进行互操作,则可以来回转换。调用添加到旧类中的新转换方法。

GregorianCalendar gc = GregorianCalendar.from( zdt ) ;
Run Code Online (Sandbox Code Playgroud)

若要将仅日期值表示为,GregorianCalendar我们必须指定一个时间和一个时区。您可能希望将一天的第一时刻用作时间部分。永远不要假设第一刻是00:00:00。诸如夏令时之类的异常意味着第一时刻可能是另一个时间,例如01:00:00。让java.time确定第一时刻。

ZonedDateTime firstMomentOfDay = ld.atZone( z ) ;
GregorianCalendar gc = GregorianCalendar.from( firstMomentOfDay ) ;
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

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

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多