tl;博士
DateTimeFormatter f = new DateTimeFormatterBuilder ().parseCaseInsensitive ().appendPattern ( "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ" ).toFormatter ().withLocale ( Locale.US );
OffsetDateTime odt = OffsetDateTime.parse ( "03-AUG-12 08.15.00.000000000 PM -05:00" , f );
对象,而不是字符串
您提到了甲骨文。从数据库中检索数据时,使用对象而不是字符串。向您的 ResultSet 询问 java.sql.Timestamp 对象。
java.sql.Timestamp ts = myResultSet.getTimestamp( … );
从麻烦的旧日期时间类转换为现代 java.time 类型。寻找在旧类上添加的新方法,以促进与 java.time 之间的转换。
Instant instant = ts.toInstant();
或者最好是,如果使用 JDBC 4.2 或更高版本,并且使用 Java 8 或更高版本,您可以通过 ResultSet::getObject 方法检索 java.time.Instant。
但如果您必须解析字符串,请继续阅读。
避免使用旧的日期时间类
与最早的 Java 版本捆绑在一起的旧日期时间类既麻烦又令人困惑。现在被 java.time 类所取代。
纳秒
那一串零必须以nanosecond 的分辨率表示几分之一秒,最多九位小数。旧的日期时间类只能处理 milliseconds,但幸运的是现代 java.time 类确实可以处理高达纳秒的分辨率。
使用 java.time
定义一个格式化模式来解析给定的输入。顺便说一句,您的数据格式不是最佳的;将来,对表示日期时间值的字符串使用ISO 8601 标准格式。
我们使用“构建器”来指定不区分大小写的解析。英文月份名称的正确缩写是 initial-cap,Aug,但您的输入使用全大写。
String pattern = "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ";
DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder ().parseCaseInsensitive ().appendPattern ( pattern );
告诉构建器实例化我们的格式化程序。 Locale 决定 (a) 用于翻译日期名称、月份名称等的人类语言,以及 (b) 决定缩写、大写、标点符号等问题的文化规范。
Locale l = Locale.US;
DateTimeFormatter f = fb.toFormatter ().withLocale ( l );
最后,将字符串解析为OffsetDateTime 对象。
String input = "03-AUG-12 08.15.00.000000000 PM -05:00";
OffsetDateTime odt = OffsetDateTime.parse ( input , f );
转储到控制台。请注意我们的晚上 8 点如何转换为 24-hour clock 值 20 小时。
System.out.println ( "input: " + input + " | odt.toString(): " + odt );
输入:03-AUG-12 08.15.00.000000000 PM -05:00 | odt.toString(): 2012-08-03T20:15-05:00
time zone 是offset-from-UTC 加上一组用于处理夏令时 (DST) 等异常的规则。如果需要,请申请 ZoneId 以获取 ZonedDateTime。
ZoneId z = ZoneId.of( “America/Montreal” );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date、.Calendar 和java.text.SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。
大部分 java.time 功能在ThreeTen-Backport 中向后移植到Java 6 和7,并进一步适应ThreeTenABP 中的Android(参见How to use…)。
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可能会在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 等等。