Different timezone id for the same short timezone name

191 Views Asked by At

I have a string "02:00:00 Feb 05, 2023 PST" which I parse:

ZonedDateTime d = ZonedDateTime.parse(nextPaymentDate, DateTimeFormatter.ofPattern("H:m:s MMM d, uuuu z"));

Comparing it a constructed date:

ZonedDateTime expectedDate = ZonedDateTime.of(2023, 2, 5, 2, 0, 0, 0, ZoneId.of(ZoneId.SHORT_IDS.get("PST")));

fails, because:

Expected :2023-02-05T02:00-08:00[America/Los_Angeles]
Actual   :2023-02-05T02:00-08:00[America/Tijuana]

Setting exact timezone id (e.g. fixing America/Tijuana) does not work, as the timezone is parsed differently on another machine (as America/Los_Angeles instead of America/Tijuana like on my machine).

How can I assert the dates are equal in this case?

2

There are 2 best solutions below

0
rolve On BEST ANSWER

The time zone abbreviations used by Java when parsing depend on the locale, so you cannot compare the result to a fixed value. See this answer.

I would convert the ZonedDateTime objects to OffsetDateTime before comparing them, or even to Instant, as Joachim suggested.

1
Arvind Kumar Avinash On

First of all, I suggest you ask the publisher of your data to avoid using abbreviated timezone IDs. In most cases, these abbreviations are 3 characters long but they may be 2 or 4 characters long (e.g. CT and AEST) as commented by Basil Bourque.

Given below is a note from the Java 7 Timezone documentation:

Three-letter time zone IDs

For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

There is already a good suggestion by Joachim Sauer. Alternatively, you can retrieve the ZoneId from the parsed date-time and use it while constructing your ZonedDateTime.

Demo:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

class Main {
    public static void main(String[] args) {
        DateTimeFormatter parser = DateTimeFormatter.ofPattern("H:m:s MMM d, uuuu z", Locale.ENGLISH);
        String strNextPaymentDate = "02:00:00 Feb 05, 2023 PST";
        ZonedDateTime zdtNextPaymentDate = ZonedDateTime.parse(strNextPaymentDate, parser);
        ZonedDateTime zdtExpectedDate = ZonedDateTime.of(2023, 2, 5, 2, 0, 0, 0, zdtNextPaymentDate.getZone());
        System.out.println(zdtNextPaymentDate);
        System.out.println(zdtExpectedDate);
    }
}

Output:

2023-02-05T02:00-08:00[America/Los_Angeles]
2023-02-05T02:00-08:00[America/Los_Angeles]

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.