tl;博士
插入/更新。
myPreparedStatement.setObject(
… ,
Instant.parse( "2010-11-22 08:08:08.123456".replace( " " , "T" ) + "Z" )
) ;
检索。
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
String output = ldt.toString().replace( "T" , " " ) ; // Remove the standard ISO 8601 format’s use of `T` in the middle with the SQL-style SPACE.
java.time
Java 8 带来了新的java.time package,以取代臭名昭著的麻烦的旧 java.util.Date、.Calendar 和 SimpleDateFormat 类。那些旧的遗留类仅限于毫秒分辨率,而您的输入字符串具有微秒。您不能将六位小数塞进限制为三位的数据类型中。
java.time 中的日期时间值具有nanosecond 分辨率,对于您的微秒来说绰绰有余。这意味着小数秒最多有 九位 位小数。
对于 JDBC 4.2 及更高版本,直接使用 Instant 类。
解析您的输入字符串。为了符合 java.time 类中默认使用的ISO 8601 格式,请将中间的空格替换为T。您给定的示例必须来自列类型TIMESTAMP WITHOUT TIME ZONE,这意味着不是特定时刻,不是时间轴上的一个点。
String input = "2010-11-22 08:08:08.123456".replace( " " , "T" ) ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
如果此输入是 UTC 中的一个时刻,请附加 Z。然后你确实有时间,时间轴上的一个特定点。用于TIMESTAMP WITH TIME ZONE 的列类型。
String input = "2010-11-22 08:08:08.123456".replace( " " , "T" ) + "Z" ;
Instant instant = Instant.parse( input ) ;
发送到您的数据库。
myPreparedStatement.setObject( … , instant ) ;
……和……
Instant instant = myResultSet.getObject( … , Instant.class ) ;
关于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。
更新:Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。保留此部分作为历史记录。
乔达时间
如上所述,您应该避免使用 java.util.Date、.Calendar 和 SimpleDateFormat 类。从 Java 8 开始,您可以选择使用 java.time 或 Joda-Time 或两者兼而有之,因为它们各有优缺点。 Joda-Time 也适用于早期版本的 Java。
您可以使用 Joda-Time 解析该字符串。
或者,如果您有权访问生成字符串的 java.sql.Timestamp,则可以简单地将 Timestamp 对象传递给 DateTime 的构造函数。我建议还传递一个时区,因为 DateTime 对象知道它们自己分配的时区。
DateTime dateTime = new DateTime( mySqlTimestamp, DateTimeZone.UTC );
或
DateTime dateTime = new DateTime( mySqlTimestamp, DateTimeZone.forID( "Europe/Paris" ) );
Joda-Time 的分辨率为 milliseconds。因此,无论哪种方式生成 DateTime(解析或传递),都会丢失秒的更精细部分(忽略/截断,未四舍五入)。