tl;博士
只使用现代的 java.time 类。永远不要使用糟糕的遗留类,例如 SimpleDateFormat、Date 或 java.sql.Timestamp。
ZonedDateTime // Represent a moment as perceived in the wall-clock time used by the people of a particular region ( a time zone).
.now( // Capture the current moment.
ZoneId.of( "Africa/Tunis" ) // Specify the time zone using proper Continent/Region name. Never use 3-4 character pseudo-zones such as PDT, EST, IST.
) // Returns a `ZonedDateTime` object.
.format( // Generate a `String` object containing text representing the value of our date-time object.
DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" )
) // Returns a `String`.
或者使用JVM的当前默认时区。
ZonedDateTime
.now( ZoneId.systemDefault() )
.format( DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" ) )
java.time & JDBC 4.2
现代方法使用如上所示的 java.time 类。
如果您的JDBC driver 符合JDBC 4.2,您可以直接与数据库交换java.time 对象。使用PreparedStatement::setObject 和ResultSet::getObject。
java.sql 仅用于 JDBC 4.2 之前的驱动程序
如果您的 JDBC 驱动程序尚不符合 JDBC 4.2 以支持 java.time 类型,则必须回退到使用 java.sql 类。
存储数据。
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ; // Capture the current moment in UTC.
myPreparedStatement.setObject( … , odt ) ;
检索数据。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
java.sql 类型,例如java.sql.Timestamp,应该只用于传入和传出数据库。在 Java 8 及更高版本中立即转换为 java.time 类型。
java.time.Instant
java.sql.Timestamp 映射到java.time.Instant,即 UTC 时间线上的时刻。注意添加到旧类中的新转换方法toInstant。
java.sql.Timestamp ts = myResultSet.getTimestamp( … );
Instant instant = ts.toInstant();
时区
应用所需/预期的时区 (ZoneId) 以获得 ZonedDateTime。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
格式化字符串
使用DateTimeFormatter 生成您的字符串。模式代码与java.text.SimpleDateFormat类似,但不完全一致,请仔细阅读文档。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "uuuu.MM.dd.HH.mm.ss" );
String output = zdt.format( formatter );
这种特殊格式的确切含义不明确,因为它没有任何offset-from-UTC 或时区的指示。
ISO 8601
如果您对此事有任何发言权,我建议您考虑使用标准的ISO 8601 格式,而不是自己滚动。标准格式与您的非常相似。例如:
2016-02-20T03:26:32+05:30。
java.time 类默认使用这些标准格式,因此无需指定模式。 ZonedDateTime 类通过附加时区名称扩展了标准格式(一个明智的改进)。
String output = zdt.toString(); // Example: 2007-12-03T10:15:30+01:00[Europe/Paris]
转换成java.sql
您可以从 java.time 转换回 java.sql.Timestamp。从ZonedDateTime 中提取Instant。
新方法已添加到旧类中,以方便与 java.time 类相互转换。
java.sql.Timestamp ts = java.sql.Timestamp.from( zdt.toInstant() );
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获取 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。