Java:解析日期字符串,时区缩写为Date对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java:解析日期字符串,时区缩写为Date对象相关的知识,希望对你有一定的参考价值。

我需要将带有时区的日期字符串解析为Date对象。输入日期字符串模式为:

"MM/dd/yyyy hh:mm a z"  (eg: 04/30/2018 06:00 PM IST).

我使用下面给出的代码。但它返回错误的日期作为输出。

new SimpleDateFormat("MM/dd/yyyy hh:mm a z").parse("04/30/2018 06:00 PM IST")

当前输出:"Mon Apr 30 09:00:00 PDT 2018"。预期产出:"Mon Apr 30 05:30:00 PDT 2018

答案

那是因为timezone's abbreviations such as IST are ambiguous。 IST在India, Israel and Ireland中使用,而SimpleDateFormat假定其中一些是默认的,以晦涩和无证的方式(AFAIK)。实际上,according to javadoc:“缩写的支持仅适用于JDK 1.1.x兼容性,应使用全名”。

使其工作的一种方法是任意选择时区并在格式化程序中设置它:

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm a z");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
Date date = sdf.parse("04/30/2018 06:00 PM IST");

始终使用Continent / Region格式的名称,例如Asia/Kolkata。这些名字是IANA's timezones names,它们并不含糊,所以这使事情有效。

java.time API

如果您使用的是Java 8或更高版本,请切换到java.time API,这要好得多。对于Java 7或更低版​​本,Threeten Backport具有相同的类和功能。

在此API中,您必须设置所有首选时区的列表,以便在IST等名称模糊时使用:

// prefered zones
Set<ZoneId> preferredZones = new HashSet<>();
preferredZones.add(ZoneId.of("Asia/Kolkata"));

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // date and time
    .appendPattern("MM/dd/yyyy hh:mm a ")
    // zone (use set of prefered zones)
    .appendZoneText(TextStyle.SHORT, preferredZones)
    // use English, because different locales can affect timezones names
    .toFormatter(Locale.ENGLISH);

ZonedDateTime zdt = ZonedDateTime.parse("04/30/2018 06:00 PM IST", fmt);

如果你仍然需要使用java.util.Date,它很容易转换:

// Java 8
Date d = Date.from(zdt.toInstant());

// Java 7 (Threenten Backport)
Date d = DateTimeUtils.toDate(zdt.toInstant());
另一答案

生成的Date对象不会包含任何时区信息。请参阅此stackoverflow thread中的类似查询

您可能在JVM的当前时区中获得了正确的日期。

如果您使用的是Java 8,那么可以使用带有时区的Date对象。看看ZonedDateTime,但为此你在解析时需要一种不同的格式化程序(DateTimeFormatter

以上是关于Java:解析日期字符串,时区缩写为Date对象的主要内容,如果未能解决你的问题,请参考以下文章

日期和时区转换[重复]

iOS Swift:当字符串包含时区缩写时,如何将特定的日期字符串格式转换为日期对象?

如何将日期字符串转换为 UTC 日期对象?

使用 JavaScript 检测时区缩写

将时区缩写解析为 UTC [重复]

将 ISO 8601 日期时间字符串转换为 **Date** 对象时,如何将日期时间重新定位到当前时区?