3

我正在尝试将其解析StringZonedDateTime

"Mon 14 Aug 2017 02:00 AM CEST"

这是我最后一次尝试:

System.out.println("Test ZonedDateTime: " + ZonedDateTime.parse(
            "Mon 14 Aug 2017 02:00 AM CEST",
            DateTimeFormatter.ofPattern("EEEE dd M yyyy KK:mm a z")));

和回应:

Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mon 14 Aug 2017 02:00 AM CEST' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)
at be.hypertux.test.localtime.Main.main(Main.java:17)

有任何想法吗?

4

2 回答 2

4

一个问题是短时区名称喜欢CESTCET模棱两可的而不是标准的。理想的情况是使用IANA 时区名称(始终采用格式Continent/City,例如America/Sao_PauloEurope/Berlin)。

我假设那CEST中欧夏令时许多不同的国家都在使用它(这就是它模棱两可的原因:你不知道它是哪个国家或地区,因为它的范围太广了)。

尽管大多数缩写不被识别(由于其模糊性),但出于追溯兼容性的原因,假定了一些“默认值”。在我使用的版本(JDK 1.8.0_131)中,它默认为Europe/Paris,但不确定这是否是您需要的。并且不能保证适用于所有缩写。在这种情况下,您可以定义要使用的首选时区(这将是一个任意选择,但没有其他方法,因为CEST它不明确)。

另一个问题是月份星期几是英文(Augand Mon),而您没有指定java.util.Locale. 在这种情况下,DateTimeFormatter采用系统的默认语言环境(可能不是英语 - 检查 的值Locale.getDefault())。无论如何,即使在运行时,默认区域设置也可以更改,恕不另行通知,因此最好在处理本地化数据(如月份星期几名称)时指定一个。

因此,您必须指定一个语言环境并定义一个任意时区作为首选时区,以便在CEST找到类似名称时使用。为此,您可以使用 a java.time.format.DateTimeFormatterBuilder、一组首选时区和 a java.time.format.TextStyle

// create set of preferred timezones
Set<ZoneId> zones = new HashSet<>();
// my arbitrary choice for CEST
zones.add(ZoneId.of("Europe/Brussels"));
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    // date and time
    .appendPattern("EEE dd MMM yyyy hh:mm a ")
    // timezone short name with custom set of preferred zones
    .appendZoneText(TextStyle.SHORT, zones)
    // create formatter (use English locale for month and day of week)
    .toFormatter(Locale.ENGLISH);

String input = "Mon 14 Aug 2017 02:00 AM CEST";
System.out.println(ZonedDateTime.parse(input, formatter));

输出将是:

2017-08-14T02:00+02:00[欧洲/布鲁塞尔]

请注意,我用作Europe/Brussels首选时区。您可以使用 . 检查所有可用的区域名称(并相应地选择)ZoneId.getAvailableZoneIds()


我正在使用hh小时,即小时时钟字段(值从 1 到 12)。但是在您使用的代码中KK,它是hour-of-am-pm字段(值从 0 到 11)。检查哪一个最适合您的情况。


时区是一个地区在其历史上拥有、拥有和将要拥有的所有不同偏移量的集合,以及夏令时开始和结束的日期等。如果 2 个地区在这段历史中存在一些差异,它们将有不同的时区(即使他们今天使用相同的规则)。

仅仅因为巴黎和布鲁塞尔今天使用相同的规则(CETCEST),并不意味着它会永远这样(因为时区规则是由政府和法律定义的,并且不能保证它们在任何时候都不会改变在将来)。

这就是为什么您必须定义一些特定的时区而不是依赖于模棱两可的短名称(即使它们的使用很普遍且广泛)。

于 2017-08-17T21:21:13.457 回答
0

为了使您的格式字符串起作用,您的日期需要像这样格式化:Monday 14 8 2017 02:00 AM CEST

取出 anE并添加几个Ms 就可以了。

于 2017-08-17T20:32:59.897 回答