不能使用以下模式使用预定义的格式,但你可以构建自己的一个(并将其分配给一个静态常量):
static final DateTimeFormatter DATE_TIME_OPTIONAL_OFFSET =
DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[xxx]");
注意:如果您解析只包含日期的输入和时间但没有偏移(并且没有任何偏移/区域默认),那么结果只能是LocalDateTime
,而不是全局时间戳。
请注意方法withZone(...)
的不同行为。
约达时间
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)
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.
侧注释:约达-时间方法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
结论:
迁移时我会小心。细节决定成败。也许更新的Java版本8u40同时纠正了一些显示的问题(至少withZone()
的行为可能已被纠正 - 请参阅JDK-issue 8033662,但对于8u31,回程修复似乎已丢失?!)。您还应该注意到,在我的测试中,标有“EST”的“时区”被替换为“America/New_York”,因为“EST”不是公认的时区标识(它在美国是一个本地时区名称缩写)。
更新 - 最终的解决方案
后额外的测试验证码似乎在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
我可以问你为什么要迁移吗? Joda-Time中存在一个特殊问题,您希望通过迁移来解决问题吗?正如您在我的回答中所看到的,迁移可能是实际操作中的挑战。如果您对Joda-Time没有任何特殊问题,并且只想迁移,因为Java-8更“现代”,那么这可能不值得所有的努力。 –
是的,你是对的。我们想要使用Java 8的所有现代功能,这就是为什么我们要迁移到Java 8的原因。 – Shishir
@MenoHochschild从Java SE 8开始,用户被要求迁移到java.time(JSR-310) 。_同样来自现场_注意Joda-Time被认为是一个大部分“完成”的项目。计划没有重大改进。如果使用Java SE 8,请迁移到java.time(JSR-310)._这些建议都出现在主页上。如果使用Java8(或更高版本),迁移是明智的。 –