converting timezone to 3 characters ZoneId

后端 未结 2 921
面向向阳花
面向向阳花 2021-01-25 05:04

I want to convert TimeZone such as \"America/Chicago\" to \"CST\". I can make use of SHORT_IDS map of ZoneID class. However, there are limited number of timezones configured in

相关标签:
2条回答
  • 2021-01-25 06:01

    Use TimeZone.getDisplayName:

    TimeZone.getTimeZone("America/Chicago").getDisplayName(false, TimeZone.SHORT)
    

    Ideone demo

    But be very careful about using three-letter time zone identifiers. Only use them for display (as implied by the method name); do not use them to identify a time zone otherwise.

    0 讨论(0)
  • 2021-01-25 06:02
        ZoneId hongKong = ZoneId.of("Asia/Hong_Kong");
        System.out.println(hongKong.getDisplayName(TextStyle.SHORT_STANDALONE, Locale.ROOT));
    

    This outputs:

    HKT

    Similarly the output for ZoneId.of("America/Chicago") is CT for Central Time (notice that this avoids the hopeless choice between CST for Central Standard Time and CDT for Central Daylight Time).

    Please supply your desired locale. In many cases it won’t make any difference, in other cases it will since some time zones have localized abbreviations in some locales.

    Unlike the outdated TimeZone class the modern ZoneId validates the time zone string and throws an exception if it is invalid, so we get a nice chance to correct any errors. For example:

    java.time.DateTimeException: Invalid ID for region-based ZoneId, invalid format: Asia/Hong Kong

    To get the abbreviation for standard time

    Edit: In this duplicate question it was asked to have the abbreviation for standard time (as opposed to summer time/DST). So CST, not CT, for America/Chicago, etc. It appeared that only US time zones needed to be supported. If so, this method does it:

    private static final DateTimeFormatter ZONE_FORMATTER
            = DateTimeFormatter.ofPattern("zzz", Locale.ENGLISH);
    
    private static String getAbbreviationForStandardTime(ZoneId zone) {
        ZonedDateTime timeInStandardTime = LocalDate.of(2021, Month.JANUARY, 1)
                .atStartOfDay(zone);
        if (zone.getRules().isDaylightSavings(timeInStandardTime.toInstant())) {
            throw new IllegalArgumentException("Time zones that have summer time on January 1 are not supported");
        }
        return timeInStandardTime.format(ZONE_FORMATTER);
    }
    

    Let’s try it out:

        System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/Los_Angeles")));
        System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/Denver")));
        System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/Chicago")));
        System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/New_York")));
    

    Output:

    PST
    MST
    CST
    EST
    

    My method includes a check that the time chosen — January 1 — is not in the summer time (DST) part of the year. For many time zones on the southern hemisphere this will fail. If you need to support any of them, the quick fix is to take July 1 instead in those cases.

    0 讨论(0)
提交回复
热议问题