我正在尝试从Joda时间库迁移到Java时间(Java 8).我无法找到相当于ISODateTimeFormat.dateOptionalTimeParser()在java.time
Joda ISO格式化程序有很好的解析器:
ISODateTimeFormat.dateTimeParser():generic - 根据解析的字符串选择解析器.同样地:
ISODateTimeFormat.dateOptionalTimeParser().
我发现很难将Joda时间改为java.time.有人可以指导我吗?
例:
String dateTimeString = "2015-01-01T12:29:22+00:00";
String dateTimeString2 = "2015-01-01T12:29:22";
Run Code Online (Sandbox Code Playgroud)
当我使用joda时解析这个字符串然后
ISODateTimeFormat.dateTimeParser().withZone("EST")
Run Code Online (Sandbox Code Playgroud)
可以处理两者而不是问题.这在java时间相当于这个?
使用java 8,带有ISO_Zoned_date_time的ZonedDateTime无法同时处理这两者.
您不能使用预定义的格式化程序,但您可以使用以下模式构建自己的格式化程序(并将其分配给静态常量):
static final DateTimeFormatter DATE_TIME_OPTIONAL_OFFSET =
DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[xxx]");
Run Code Online (Sandbox Code Playgroud)
注意:如果解析仅包含日期和时间但没有偏移(并且没有任何偏移/区域默认值)的输入,则结果只能是a LocalDateTime,而不是全局时间戳.
还请注意方法的不同行为withZone(...).
乔达时间
Run Code Online (Sandbox Code Playgroud)When parsing, this zone will be set on the parsed datetime. A null zone means of no-override. If both an override chronology and an override zone are set, the override zone will take precedence over the zone in the chronology.
Java-8(JSR-310)
Run Code Online (Sandbox Code Playgroud)When parsing, there are two distinct cases to consider. If a zone has been parsed directly from the text, perhaps because DateTimeFormatterBuilder.appendZoneId() was used, then this override Zone has no effect. If no zone has been parsed, then this override zone will be included in the result of the parse where it can be used to build instants and date-times.
旁注:Joda-Time方法withOffsetParsed()更接近Java-8行为.
更新:我现在已经完成了自己的测试.看到有时令人惊讶的结果.
System.out.println(System.getProperty("java.version")); // 1.8.0_31
// parsing s1 with offset = UTC
String s1 = "2015-01-01T12:29:22+00:00";
OffsetDateTime odt1 = DATE_TIME_OPTIONAL_OFFSET.parse(s1, OffsetDateTime::from);
System.out.println(odt1); // 2015-01-01T12:29:22Z --- OK
LocalDateTime ldt1 = DATE_TIME_OPTIONAL_OFFSET.parse(s1, LocalDateTime::from);
System.out.println(ldt1); // 2015-01-01T12:29:22 --- OK
ZonedDateTime zdt1 = DATE_TIME_OPTIONAL_OFFSET.withZone(ZoneId.of("America/New_York")).parse(s1, ZonedDateTime::from);
System.out.println(zdt1); // 2015-01-01T12:29:22-05:00[America/New_York] --- seems to be a bug compared with the spec above, the parsed offset was overridden!!!
// now parsing s2 without offset
String s2 = "2015-01-01T12:29:22";
OffsetDateTime odt2 = DATE_TIME_OPTIONAL_OFFSET.parse(s2, OffsetDateTime::from);
System.out.println(odt2); // 2015-01-01T12:29:22Z --- questionable, the offset Z is invented/guessed here
LocalDateTime ldt2 = DATE_TIME_OPTIONAL_OFFSET.parse(s2, LocalDateTime::from);
System.out.println(ldt2); // 2015-01-01T12:29:22 --- OK
DATE_TIME_OPTIONAL_OFFSET.withZone(ZoneId.of("America/New_York")).parse(s2, ZonedDateTime::from);
// throws an exception --- seems to be a bug compared with the spec above, the zone set was not accepted
Run Code Online (Sandbox Code Playgroud)
结论:
迁移时我会小心.细节决定成败.也许更新的Java版本8u40同时纠正了所显示的一些问题(至少行为withZone()可能已得到纠正 - 请参阅JDK-issue 8033662,但对于8u31,后端修复似乎丢失了?!).您还应该注意,在我的测试中,标有"EST"的"时区"被"America/New_York"取代,因为"EST"不是公认的时区ID(它在美国是一个本地化的时区名称缩写).
更新 - 最终解决方案
经过额外的测试后,这段代码似乎在Java 8u31中工作(假设UTC在输入中缺少偏移量时为默认值):
static final DateTimeFormatter DATE_TIME_OPTIONAL_OFFSET =
DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[xxx]");
OffsetDateTime odt =
DATE_TIME_OPTIONAL_OFFSET.withZone(ZoneOffset.UTC).parse(input, OffsetDateTime::from);
ZonedDateTime zdt = odt.toZonedDateTime(); // containing a fixed offset
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3000 次 |
| 最近记录: |