tl;博士
使用对象,而不是字符串。
myPreparedStatement.setObject(
… ,
ZonedDateTime.parse(
"Wed Oct 11 17:30:20 CEST 2017" ,
DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss z uuuu" , Locale.US )
).toInstant()
)
java.time
使用 JDBC 4.2 及更高版本,您可以直接与数据库交换 java.time 对象。 无需纠结于单纯的字符串,也无需使用麻烦的旧日期时间类,例如 java.sql.Date/java.sql.Timestamp。
为您的输入定义格式模式。指定 Locale 以指示翻译日期名称和月份名称所需的人类语言。
String input = "Wed Oct 11 17:30:20 CEST 2017";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss z uuuu" , Locale.US );
解析为ZonedDateTime,因为您的输入包含有关时区的提示。请注意,您的CEST 实际上不是时区,但ZonedDateTime 会猜测解释。这种 3-4 个字母的伪区域给出了有关时区的提示,但不是标准化的,甚至不是唯一的(!)。这与输入字符串的其余部分一起,是日期时间格式的糟糕选择。尽可能使用标准的ISO 8601 格式。
以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
通常最好在 UTC 工作。提取一个Instant 对象。 Instant 类代表UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。
Instant instant = zdt.toInstant() ;
通过支持 JDBC 4.2 或更高版本的 JDBC driver 将其传递到您的数据库。
myPreparedStatement.setObject( … , instant ) ;
检索:
Instant instant = myResultSet.getObject( … , Instant.class ) ;
如果您的数据库列的类型是 TIMESTAMP WITHOUT TIME ZONE 而不是 TIMESTAMP WITH TIME ZONE,则使用 LocalDateTime 对象而不是 ZonedDateTime/Instant。 LocalDateTime 对象缺少 time zone 或 offset-from-UTC 的任何概念。
LocalDateTime ldt = zdt.toLocalDateTime() ;
myPreparedStatement.setObject( … , ldt ) ;
旧版java.util.Date
如果您的 Twitter 调用实际上返回了 java.util.Date 对象而不是字符串,请转换为 Instant 并按照上述步骤进行测试。
Instant instant = myJavaUtilDate.toInstant() ; // Convert from troublesome legacy `Date` class to modern `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 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。