ZonedDateTime format and parsing exception with “z” in format pattern

1.1k views Asked by At

I have a problem with parsing ZonedDateTime:

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-ddzhh:mm");
ZonedDateTime.parse(s, formatter);

This results in an error:

java.time.format.DateTimeParseException:
    Text '2022-05-24UTC12:15' could not be parsed at index 10

whats wrong with this code?

2

There are 2 answers

10
deHaar On BEST ANSWER

The character z should be able to parse "UTC" (in most Locales) because UTC is considered a time-zone ID and a time-zone name in java.time. A VV can parse time-zone ids while zcan parse time-zone-names according to the JavaDocs of java.time.DateTimeFormatter, here's the relevant part of the docs:

Symbol  Meaning                     Presentation      Examples
------  -------                     ------------      -------
(…)

V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
z       time-zone name              zone-name         Pacific Standard Time; PST

(…)

That means you can parse it using the character V without providing a specific Locale to your DateTimeFormatter. You will have to put two of them (VV) or you will get a nice IllegalArgumentException with the following message:

java.lang.IllegalArgumentException: Pattern letter count must be 2: V

If you still want to use z, provide a Locale that considers UTC an abbreviation of Universal Time Coordinated, the Central European Summer Time is an abbreviation that definitely changes among different Locales, e.g.

  • English: CEST
  • German: MESZ

Other Locales might have different abbreviations, which makes me wonder if your Locale actually even has a different one for UTC.
Provide Locale.ENGLISH, for example and it should parse successfully.

You should provide one anyway because if you don't, the DateTimeFormatter will implicitly use the default Locale of your (Java Virtual) machine.

So you can try this:

DateTimeFormatter format = DateTimeFormatter.ofPattern("uuuu-MM-ddVVHH:mm");

or this:

DateTimeFormatter format = DateTimeFormatter.ofPattern("uuuu-MM-ddzHH:mm", Locale.ENGLISH);

both should be able to parse an input like "2022-05-24UTC12:15" if you use HH instead of hh for hours of day (hh = 12h format, HH = 24h format).

2
Mohammed El Amine Mahmoudi On

Yes it's because of formatter pattern, i suggest to use the code below :

    final DateTimeFormatter format
            = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");

    ZonedDateTime zonedDateTime = ZonedDateTime
            .parse("2022-05-24 14:30:30 -01:00", format);
    
    System.out.println(zonedDateTime);

    ZonedDateTime localTimeline = zonedDateTime
            .withZoneSameInstant(ZoneId.systemDefault());

    // for the local timezone
    System.out.println(localTimeline);