我有一个LocalDateTime实例,我从存储库层获取,我需要将其转换为时间戳(协议缓冲区)实例。
我已经习惯了以下方法进行转换:
LocalDateTime localDateTime = LocalDateTime.now();//this can be any date
Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.newBuilder()
.setSeconds(instant.getEpochSecond())
.setNanos(instant.getNano())
.build();
这里使用ZoneOffset,将localDateTime转换为Instant的实例,对吗?
我使用了UTC偏移量,因为Timestamp类中“seconds”属性的注释说明如下:
表示自Unix纪元1970-01-01T00:00:00Z以来的UTC时间秒。 必须是0001-01-01T00:00:00Z至9999-12-31T23:59:59Z包含
我是否使用了正确的ZoneOffset并且我的转换方法是否正确?
答案 0 :(得分:1)
一般情况下,不,您的方法不正确。原因是LocalDateTime
没有关联的时区,因此它本质上是模糊的。要将其转换为实际时间戳(绝对时间点,与时区无关),您需要知道测量的时区。
通过调用localDateTime.toInstant(ZoneOffset.UTC)
,您假设您的localDateTime
实际上是在UTC时区内测量的。 相反,您应该使用存储LocalDateTime
的时区。如果您不知道,那么您的输入数据本质上是不明确的,您需要先修复它。
请注意,这与Unix纪元通常以UTC指定的事实无关。我们不妨说Unix时代是1970-01-01T08:00:00+08:00
,它会在同一时刻出现。
其余部分对我来说似乎是正确的。
答案 1 :(得分:0)
这是一个将问题和 actual answer 中的评论汇总到此问题的例程:
protected Timestamp convertLocalDateTimeToGoogleTimestamp(LocalDateTime localDateTime) {
Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
Timestamp result = Timestamp.newBuilder()
.setSeconds(instant.getEpochSecond())
.setNanos(instant.getNano())
.build();
return result;
}