Joda DateTimeFormatter.parseDateTime 对于一般时区('z')失败 [英] Joda DateTimeFormatter.parseDateTime is failing for General time zone('z')

查看:76
本文介绍了Joda DateTimeFormatter.parseDateTime 对于一般时区('z')失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对通用时区('z')的使用感到困惑.Joda 在下面的示例代码中失败了.有人可以帮我理解为什么会这样吗?如何在 Joda 中使用这种格式解析不同时区的日期?

 public static void main(String[] args) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");System.out.println(sdf.parse("2019.09.17 AD at 15:29:00 IST"));DateTimeFormatter 模式 = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");System.out.println(dateCtxParamDateTimeObj.toDate());}

输出

2019 年 9 月 17 日星期二 15:29:00 IST线程main"java.lang.IllegalArgumentException 中的异常:格式无效:2019.09.17 AD at 15:29:00 IST"在IST"处格式错误在 org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:945)

解决方案

你需要告诉 Joda-Time 你所说的 IST 是什么意思

感谢 HarryQ,他指出了我 这里到这里记录在案.

 DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap("IST", DateTimeZone.forID("欧洲/都柏林")));DateTimeFormatter 模式 = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");System.out.println(dateCtxParamDateTimeObj);

此代码段的输出是:

<块引用>

2019-09-17T15:29:00.000+01:00

格式模式字符串中的小写 z 在格式化和在 Joda-Time 中解析时的工作方式不同.Joda-Time 可以格式化所有可用时区的时区名称,但使用默认设置它只能解析几个.它可以解析的内容由 DateTimeUtils 类的 默认时区名称 控制.它带有 10 个时区缩写的地图,如 DateTimeUtils.getDefaultTimeZoneNames 方法(底部链接)中所述:CST、MDT、GMT、PST、PDT、UTC、EDT、CDT、EST 和MST.我们可以用不同的地图代替.我在上面所做的只是用一个缩写的地图代替插图.这可能会破坏其他代码,因此对于大多数用途而言,更好的方法是构建一个地图,其中包含之前存在的缩写词以及我们希望能够解析的缩写词.

我在上面提供的地图假定 IST 适用于爱尔兰夏令时(2019 年 9 月 17 日,爱尔兰使用夏令时 (DST)).您几乎不是指以色列标准时间,因为以色列也使用夏季时间,IDT.第三种可能的理解是印度标准时间:

 DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap("IST", DateTimeZone.forID("亚洲/加尔各答")));

<块引用>

2019-09-17T15:29:00.000+05:30

您注意到我们现在得到的偏移量是 +05:30 而不是 +01:00,所以是不同的时间点.歧义也可能是 Joda-Time 拒绝对您的意图做出自己的假设的原因,因此需要我们在它解析字符串之前告诉它.

原答案

这是 Joda-Time 中记录的限制.来自 DateTimeFormat 的文档:

<块引用>

区域名称:无法解析时区名称 ('z').

还要注意 IST 和许多其他时区缩写是模棱两可的,所以如果有任何方法可以避免解析一个,请务必避免它.IST 可能代表爱尔兰夏令时间、以色列标准时间或印度标准时间,并且无法保证您获得的是哪一个,或者您是否可能获得冰岛标准时间.

如果您坚持,一种可能的解决方案是遵循 Joda-Time 主页上的建议:

<块引用>

请注意,Joda-Time 被认为是一个基本上已完成"的项目.没有计划进行重大改进.如果使用 Java SE 8,请迁移到 java.time (JSR-310).

DateTimeFormatter 类 java.time(现代 Java 日期和时间 API)将尝试解析时区缩写.祝你好运.

链接

乔达时间

其他

  • 我的回答展示了如何在使用 java.time 进行解析时控制 IST 的解释.

Confused with the use of General time zone('z'). Joda is failing in below sample code. Can somebody help me to understand why the behavior is like this? How can I parse a date in differnt timezone using this format in Joda?

    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
        System.out.println(sdf.parse("2019.09.17 AD at 15:29:00 IST"));

        DateTimeFormatter pattern = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");
        DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");
        System.out.println(dateCtxParamDateTimeObj.toDate());
    }

Output

Tue Sep 17 15:29:00 IST 2019
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "2019.09.17 AD at 15:29:00 IST" is malformed at "IST"
    at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:945)

解决方案

Edit: You need to tell Joda-Time what you mean by IST

Thanks go to HarryQ, who pointed me here to where this is documented.

    DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap(
            "IST", DateTimeZone.forID("Europe/Dublin")));

    DateTimeFormatter pattern = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");
    DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");

    System.out.println(dateCtxParamDateTimeObj);

The output from this snippet is:

2019-09-17T15:29:00.000+01:00

Lowercase z in a format pattern string works differently when formatting and when parsing in Joda-Time. Joda-Time can format time zone names for all available time zones, but with default settings it can only parse a few back. Which it can parse is controlled by the default time zone names of the DateTimeUtils class. It comes with a map of 10 time zone abbreviations as documented in the DateTimeUtils.getDefaultTimeZoneNames method (link at the bottom): CST, MDT, GMT, PST, PDT, UTC, EDT, CDT, EST and MST. We can substitute with a different map. What I am doing above is substituting with a map of just one abbreviation for the illustration. This risks breaking other code, so a better approach for most purposes would be to build a map containing both the abbreviations that were there before and that or those that we want to be able to parse too.

The map I provided above assumes that IST is for Irish Summer Time (and on September 17, 2019, Ireland was using summer time (DST)). You hardly meant Israel Standard Time because Israel too used summer time, IDT. A third likely understanding is India Standard Time:

    DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap(
            "IST", DateTimeZone.forID("Asia/Kolkata")));

2019-09-17T15:29:00.000+05:30

You notice that we now get offset +05:30 instead of +01:00, so a different point in time. The ambiguity may also be the reason why Joda-Time refuses to make its own assumption about what you intended and therefore needs us to tell it before it can parse the string.

Original answer

It’s a documented limitation in Joda-Time. From the documentation of DateTimeFormat:

Zone names: Time zone names ('z') cannot be parsed.

Also note that IST and many other time zone abbreviations are ambiguous, so if there is any way you can avoid parsing one, by all means do avoid it. IST may be for Irish Summer Time, Israel Standard Time or India Standard Time, and there’s no guarantee which of them you get, or if you may even get Iceland Standard Time.

If you insist, one possible solution is to follow the advice from the Joda-Time homepage:

Note that Joda-Time is considered to be a largely "finished" project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).

The DateTimeFormatter class of java.time (the modern Java date and time API) will attempt to parse a time zone abbreviation. Good luck.

Links

Joda-Time

Others

  • My answer here shows how to control the interpretation of IST while parsing when using java.time.

这篇关于Joda DateTimeFormatter.parseDateTime 对于一般时区('z')失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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