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

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


翻阅古今
浏览 287回答 3
3回答

蝴蝶刀刀

作为 UTC 中的一个时刻,转换为java.time.Instant. 然后应用时区以获取ZonedDateTime. 将仅日期部分提取为LocalDate.单线:Instant.ofEpochSecond( ts.getSeconds() , ts.getNanos() ) .atZone( ZoneId.of( "America/Montreal" ) ) .toLocalDate() 转变第一步是将Timestamp对象的秒数和小数秒(纳秒)转换为java.time类。具体来说,java.time.Instant。就像Timestamp, anInstant代表 UTC 中的一个时刻,分辨率为纳秒。Instant instant =  Instant.ofEpochSecond( ts.getSeconds() , ts.getNanos() ) ;确定日期需要时区。对于任何给定时刻,日期因地区而异。将 a 应用ZoneId到 ourInstant以获得ZonedDateTime. 同一时刻,时间线上的同一点,不同的挂钟时间。ZoneId z = ZoneId( "Pacific/Auckland" ) ; ZonedDateTime zdt = instant.atZone( z ) ;将仅日期部分提取为LocalDate. ALocalDate没有时间和时区。LocalDate ld = zdt.toLocalDate() ;注意:不要不使用LocalDateTime类用于此目的,在另一个答案不幸所示。该类故意缺少时区或UTC偏移量的任何概念。因此,它不能代表一个时刻,也不是时间线上的一个点。请参阅类文档。转变最好完全避免非常麻烦的遗留日期时间类,包括Date, Calendar, SimpleDateFormat。但是,如果您必须与尚未更新为java.time 的旧代码进行互操作,则可以来回转换。调用添加到旧类的新转换方法。GregorianCalendar gc = GregorianCalendar.from( zdt ) ;要将仅日期值表示为 a,GregorianCalendar我们必须指定时间和时区。您可能希望使用一天中的第一时刻作为时间组件。永远不要假设第一个时刻是 00:00:00。夏令时等异常意味着第一个时刻可能是另一个时间,例如 01:00:00。让java.time确定第一时刻。ZonedDateTime firstMomentOfDay = ld.atZone( z ) ;GregorianCalendar gc = GregorianCalendar.from( firstMomentOfDay ) ;

蝴蝶不菲

首先请注意:Protobuf 的TimeStamp分辨率(秒和几分之一秒)比 Java 的LocalDate(天)更高,因此您将通过从 转换TimeStamp为LocalDate请参阅 TimeStamp 的JavaDoc 的摘录:时间戳表示独立于任何时区或日历的时间点,以 UTC 纪元时间的纳秒分辨率表示为秒和秒的分数。这个 JavaDoc 告诉我们,该值是基于纪元时间的表示,这意味着我们可以使用 Java 的LocalDateTime#ofEpochSeconds进行无损转换(因为LocalDateTime也存储时间),然后从那里剥离时间以获得LocalDate.通过使用LocalDateTime(em: Local),我们可以确保我们使用与类相同的时区偏移量TimeStamp,即 UTC(再次来自 JavaDoc):final Timestamp ts1 = Timestamp.newBuilder().setSeconds((60 * 60 * 24) - 1).build();final Timestamp ts2 = Timestamp.newBuilder().setSeconds((60 * 60 * 24)).build();final LocalDate ld1 = LocalDateTime.ofEpochSecond(ts1.getSeconds(), ts1.getNanos(), ZoneOffset.UTC).toLocalDate();final LocalDate ld2 = LocalDateTime.ofEpochSecond(ts2.getSeconds(), ts2.getNanos(), ZoneOffset.UTC).toLocalDate();System.out.println(ts1 + " = " + ld1);System.out.println(ts2 + " = " + ld2);输出秒:86399 = 1970-01-01秒:86400 = 1970-01-02要求转换为后编辑java.util.Date查看可能的构造函数Date及其JavaDoc,我们发现:分配一个 Date 对象并将其初始化为表示自称为“纪元”的标准基准时间(即格林威治标准时间 1970 年 1 月 1 日 00:00:00)以来的指定毫秒数。并且因为 GMT 是用于分区时间表示的旧标准并且它基本上是 UTC +/- 0,所以这个构造函数符合我们的需要:TimeZone.setDefault(TimeZone.getTimeZone("UTC"));// making sure the Date objects use UTC as timezonefinal Timestamp ts1 = Timestamp.newBuilder().setSeconds((60 * 60 * 24) - 1).build();final Timestamp ts2 = Timestamp.newBuilder().setSeconds((60 * 60 * 24)).build();final Date d1 = new Date(ts1.getSeconds() * 1000);final Date d2 = new Date(ts2.getSeconds() * 1000);System.out.println(ts1 + " = " + d1);System.out.println(ts2 + " = " + d2);输出:秒:86399 = 1970 年 1 月 1 日星期四 23:59:59 CET秒:86400 = 1970 年 1 月 2 日星期五 00:00:00 CET
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java