从Joda时间库迁移到Java时间(Java 8) [英] migrate from Joda time library to Java time(Java 8)

查看:306
本文介绍了从Joda时间库迁移到Java时间(Java 8)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Joda时间库迁移到Java时间(Java 8)。
我无法在 java.time

I am trying to migrate from Joda time library to Java time (Java 8). I am unable to find equivalent of ISODateTimeFormat.dateOptionalTimeParser() in java.time

Joda ISO格式化程序有很好的解析器:

Joda ISO formatter has nice parsers:

ISODateTimeFormat.dateTimeParser():generic - 根据解析的字符串选择解析器。
同样:
ISODateTimeFormat.dateOptionalTimeParser()

ISODateTimeFormat.dateTimeParser() : generic - selects parser based on string parsed. Similarly: ISODateTimeFormat.dateOptionalTimeParser().

我发现很难将Joda时间更改为java.time。
有人可以指导我吗?

I am finding it difficult to change Joda time to java.time. Can some one guide me?

示例:

String dateTimeString = "2015-01-01T12:29:22+00:00"; 
String dateTimeString2 = "2015-01-01T12:29:22";

当我使用joda时间解析此字符串时

When I parse this string using joda time then

ISODateTimeFormat.dateTimeParser().withZone("EST")

可以解决这两个问题。这在java时间相当于这个?

can handle both without as problem. Which is equivalent of this in java time?

使用java 8,带有ISO_Zoned_date_time的ZonedDateTime无法同时处理这两个。

Using java 8, ZonedDateTime with ISO_Zoned_date_time is not able to handle both.

推荐答案

您不能使用预定义的格式化程序,但您可以使用以下模式构建自己的格式化程序(并将其指定为静态常量):

You cannot use a predefined formatter but you can construct your own one (and assign it to a static constant) using following pattern:

static final DateTimeFormatter DATE_TIME_OPTIONAL_OFFSET =
    DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[xxx]");

注意:如果您解析的输入只包含日期和时间但没有offset(并且没有任何offset / zone-default)然后结果只能是 LocalDateTime ,而不是全局时间戳。

Attention: If you parse an input containing only date and time but without offset (and without any offset/zone-default) then the result can only be a LocalDateTime, not a global timestamp.

请注意方法 withZone(...)的不同行为。

Please also note the different behaviour of method withZone(...).

Joda -Time


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.


旁注:Joda-Time-method withOffsetParsed()更接近Java-8行为。

Side remark: The Joda-Time-method withOffsetParsed() is closer to Java-8-behaviour.

更新:我现在已经完成了自己的测试。查看有时令人惊讶的结果。

Update: I have now done my own tests. See the sometimes surprising results.

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不是公认的时区ID(它在美国是一个本地化的时区名称缩写)。

I would be careful when migrating. The devil is in the details. Maybe a newer Java-version 8u40 has meanwhile corrected some of the problems shown (at least the behaviour of withZone() is probably corrected - see JDK-issue 8033662, but for 8u31 the backport fix appears to be missing?!). You should also note that your "timezone" labelled "EST" was replaced by "America/New_York" in my tests because "EST" is not a recognized timezone id (it is rather a localized timezone name abbreviation in US).

更新 - 最终解决方案

经过额外测试后,此代码似乎适用于Java 8u31(假设在输入中缺少偏移量时UTC为默认值:

After extra testing this code seems to work in Java 8u31 (assuming UTC as default in case of missing offset in input):

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时间库迁移到Java时间(Java 8)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆