tl;dr
作为 UTC 时刻,转换为java.time.Instant
。然后应用时区以获得ZonedDateTime
。将仅日期部分提取为LocalDate
.
单线:
Instant
.ofEpochSecond( ts.getSeconds() , ts.getNanos() )
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
Convert
第一步是转换Timestamp https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Timestamp对象的秒数和小数秒(纳秒)java.time类。具体来说,java.time.Instant https://docs.oracle.com/javase/10/docs/api/java/time/Instant.html。就像Timestamp
, an Instant
表示 UTC 中的一个时刻,分辨率为纳秒。
Instant instant = Instant.ofEpochSecond( ts.getSeconds() , ts.getNanos() ) ;
确定日期需要时区。对于任何特定时刻,全球各地的日期都会因地区而异。
Apply a ZoneId
to our Instant
得到一个ZonedDateTime
。同一时刻,时间轴上的同一点,不同的挂钟时间。
ZoneId z = ZoneId( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
将仅日期部分提取为LocalDate
. A LocalDate
没有时间和时区。
LocalDate ld = zdt.toLocalDate() ;
注意:做not use LocalDateTime
用于此目的的类,不幸的是,如另一个答案所示。该类故意缺少任何时区或与 UTC 的偏移量的概念。因此它不能代表一个时刻,也不是时间线上的一个点。请参阅类文档。
Convert
最好完全避免非常麻烦的遗留日期时间类,包括Date
, Calendar
, SimpleDateFormat
。但是,如果您必须与尚未更新的旧代码进行互操作java.time您可以来回转换。调用添加到旧类中的新转换方法。
GregorianCalendar gc = GregorianCalendar.from( zdt ) ;
将仅日期值表示为GregorianCalendar
我们必须指定一天中的时间和时区。您可能希望使用一天中的第一时刻作为一天中的时间部分。永远不要假设第一时刻是 00:00:00。夏令时等异常意味着第一个时刻可能是另一个时间,例如 01:00:00。让java.time确定第一时刻。
ZonedDateTime firstMomentOfDay = ld.atZone( z ) ;
GregorianCalendar gc = GregorianCalendar.from( firstMomentOfDay ) ;
About java.time
The java.time http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html框架内置于 Java 8 及更高版本中。这些课程取代了麻烦的旧课程legacy https://en.wikipedia.org/wiki/Legacy_system日期时间类,例如java.util.Date https://docs.oracle.com/javase/10/docs/api/java/util/Date.html, Calendar https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html, & SimpleDateFormat http://docs.oracle.com/javase/10/docs/api/java/text/SimpleDateFormat.html.
The 乔达时间 http://www.joda.org/joda-time/项目,现在在维护模式 https://en.wikipedia.org/wiki/Maintenance_mode,建议迁移到java.time http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html类。
要了解更多信息,请参阅甲骨文教程 http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310 https://jcp.org/en/jsr/detail?id=310.
您可以交换java.time对象直接与您的数据库。用一个JDBC驱动程序 https://en.wikipedia.org/wiki/JDBC_driver符合JDBC 4.2 http://openjdk.java.net/jeps/170或稍后。不需要字符串,不需要java.sql.*
类。
从哪里获取 java.time 类?
-
Java SE 8 https://en.wikipedia.org/wiki/Java_version_history#Java_SE_8, Java SE 9 https://en.wikipedia.org/wiki/Java_version_history#Java_SE_9, Java SE 10 https://en.wikipedia.org/wiki/Java_version_history#Java_SE_10, Java SE 11 https://en.wikipedia.org/wiki/Java_version_history#Java_SE_11, and later - Part of the standard Java API with a bundled implementation.
-
Java SE 6 https://en.wikipedia.org/wiki/Java_version_history#Java_SE_6 and Java SE 7 https://en.wikipedia.org/wiki/Java_version_history#Java_SE_7
- 大多数 java.time 功能都向后移植到 Java 6 和 7三十后端口 http://www.threeten.org/threetenbp/.
-
Android https://en.wikipedia.org/wiki/Android_(operating_system)
- 更高版本的 Android 捆绑实现java.time类。
- 对于早期的 Android (三十ABP项目适应三十后端口 http://www.threeten.org/threetenbp/(上文提到的)。看如何使用 ThreeTenABP... http://stackoverflow.com/q/38922754/642706.
The 三十额外 http://www.threeten.org/threeten-extra/项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如Interval http://www.threeten.org/threeten-extra/apidocs/org/threeten/extra/Interval.html, YearWeek http://www.threeten.org/threeten-extra/apidocs/org/threeten/extra/YearWeek.html, YearQuarter http://www.threeten.org/threeten-extra/apidocs/org/threeten/extra/YearQuarter.html, and more http://www.threeten.org/threeten-extra/apidocs/index.html.