1

Ugh... I can't figure this out for the life of me. I'm using Java 8 and trying do to something as simple as parsing a timestamp where the TimeZone ID is a textual value such as HST:

WORKS

ZonedDateTime timestamp = ZonedDateTime.parse("2018-10-29T12:00:12.456-10:00");

DOES NOT WORK

ZonedDateTime timestamp = ZonedDateTime.parse("2018-10-29T12:00:12.456HST");

And get this error:

java.time.format.DateTimeParseException: Text '2018-10-29T12:00:12.456HST' could not be parsed at index 23

Does anyone know how to parse a timestampe where the timezone ID comes in as a textual value?

  • 1
    https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html#parse-java.lang.CharSequence-java.time.format.DateTimeFormatter-, https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html, https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ofPattern-java.lang.String- – JB Nizet Jan 05 '19 at 18:19
  • Try if you can avoid relying on parsing a three letter time zone abbreviation. They are not standardized, so there’s no guarantee what you get. While HST may only mean Hawaii Standard Time, the most used abbreviations including PST, CST and EST are ambiguous. – Ole V.V. Jan 07 '19 at 10:35

1 Answers1

3

There are two problems:

1) ZonedDateTime.parse method parse only strings that obey the ISO_ZONED_DATE_TIME format, description of how it looks you can find here: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_ZONED_DATE_TIME

In order to parse your format you have to create your own dateTimeFormatter.

This formatter can look like this

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral('T')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendZoneId()
            .toFormatter();

This formatter would work if you would use standart zones like GMT, UTC etc.. Problem is that HST is not standard format for Zone and is not supported. You can see supported time zones via:

System.out.println(ZoneId.getAvailableZoneIds());

If you still want to use HST zone you have to add ZoneRulesProvider for your custom zone like this:

  ZoneRulesProvider.registerProvider(new ZoneRulesProvider() {
        @Override
        protected Set<String> provideZoneIds() {
            return Collections.singleton("HST");
        }

        @Override
        protected ZoneRules provideRules(String zoneId, boolean forCaching) {
            return ZoneRules.of(ZoneOffset.ofHours(10));
        }

        @Override
        protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
            TreeMap map =  new TreeMap<>();
            map.put("HST",ZoneRules.of(ZoneOffset.ofHours(10)));
            return  map;
        }
    });

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral('T')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendZoneId()                
            .toFormatter();

    ZonedDateTime timestamp = ZonedDateTime.parse("2018-10-29T12:00:12.456HST", formatter);
    System.out.println(timestamp);

THis should work.

HPCS
  • 1,434
  • 13
  • 22
  • HST seems to be supported here, and appears to be a synonym of Pacific/Honolulu. – JB Nizet Jan 05 '19 at 18:59
  • 1
    You can use HST, but HST is not supported by Java ZoneId, because its non-standard, more about that you can find here: https://stackoverflow.com/questions/18405262/what-are-the-standard-timezone-abbreviations/18407231#18407231 . Java expects the whole string "Pacific/Honolulu" to be used as ZoneId, if you want to use HST as ZoneId you have to register your own ZoneRulesProvider – HPCS Jan 05 '19 at 19:08
  • 2
    Right. It's not aZoneId. But it's a recognized zone name. Simply using `DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz")`allows parsing the string. – JB Nizet Jan 05 '19 at 19:21
  • Nice, much better solution. – HPCS Jan 05 '19 at 19:31
  • 2
    `HST` is [deprecated as an identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). See the [*Hawaii–Aleutian Time Zone*](https://en.wikipedia.org/wiki/Hawaii–Aleutian_Time_Zone). Ideally, the publisher issuing these strings should be educated about using a proper time zone name such as `Pacific/Honolulu`. – Basil Bourque Jan 05 '19 at 19:46
  • Thanks HPCS that did the trick! Unfortunately, I have no control over what the publisher is sending me so for now I'll just have to hack in HST (possibly others). Thanks again, helped a lot! Voting this up :) – Albert Rannetsperger Jan 05 '19 at 22:16