Joda DateTimeFormatter.parseDateTime在常规时区('z')中失败 [英] Joda DateTimeFormatter.parseDateTime is failing for General time zone('z')

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

问题描述

与通用时区('z')的使用混淆. Joda在以下示例代码中失败.有人可以帮助我理解为什么这样的行为吗?如何在Joda中使用这种格式解析不同时区中的日期?

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());
    }

输出

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)

推荐答案

您需要告诉Joda-Time IST的含义

感谢转到 HarryQ ,他指出了我

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);

此代码段的输出为:

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

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

在格式化和在Joda-Time中进行解析时,格式模式字符串中的

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

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.

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

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

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

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

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.

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

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

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

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

还要注意,IST和许多其他时区缩写是模棱两可的,因此,如果有任何方法可以避免解析,则一定要避免使用它. IST可能适用于爱尔兰的夏令时,以色列的标准时间或印度的标准时间,因此无法保证您会获得其中的哪一个,甚至无法获得冰岛的标准时间.

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.

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

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

请注意,Joda-Time被认为是很大程度上完成"的项目. 没有计划进行重大增强.如果使用Java SE 8,请迁移 到java.time(JSR-310).

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).

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

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

Joda-Time

  • Documentation of DateTimeUtils.getDefaultTimeZoneNames()
  • Related question: Why Joda DateTimeFormatter cannot parse timezone names ('z')
  • Documentation of DateTimeFormat
  • Joda-Time homepage
  • SO user HarryQ, who in comments under my answer to this duplicate question pointed me to the documentation of Joda-Time’s default time zone names.

其他

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

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

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