Java: Parse Date String with timezone abbreviations to Date object

馋奶兔 提交于 2021-02-10 15:24:19

问题


I need to parse a date string with timezone to Date object. The input date string pattern is:

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

I have used below given code. But it returns incorrect date as output.

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

Current Output: "Mon Apr 30 09:00:00 PDT 2018". Expected Output: "Mon Apr 30 05:30:00 PDT 2018.


回答1:


That's because timezone's abbreviations such as IST are ambiguous. IST is used in India, Israel and Ireland, and SimpleDateFormat assumes some of them as default, in obscure and undocumented ways (AFAIK). Actually, according to javadoc: "support of abbreviations is for JDK 1.1.x compatibility only and full names should be used".

One way to make it work is to arbitrarily choose a timezone and set it in the formatter:

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

Always use names in the format Continent/Region, such as Asia/Kolkata. Those names are IANA's timezones names, and they are not ambiguous, so this make things work.

java.time API

If you're using Java 8 or higher, switch to the java.time API, which is much better. For Java 7 or lower, there's the Threeten Backport with the same classes and functionality.

In this API, you must set a list of all preferred timezones to be used in case of ambiguous names like 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);

If you still need to use java.util.Date, it's easy to convert:

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

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



回答2:


The resultant Date object will not hold any timezone information. See the similar query in this stackoverflow thread

You might be getting the correct date but in your JVM's current timezone.

In case if you are using Java 8, then there's a provision of Date object with timezone. Look at ZonedDateTime, but for this you need a different kind of formatter while parsing (DateTimeFormatter)



来源:https://stackoverflow.com/questions/49612111/java-parse-date-string-with-timezone-abbreviations-to-date-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!