Search code examples
javadatetimetimezonedatetime-formatzoneid

How to use locale for Java ZoneId?


Having an issue when translating my date to other languages. The way its displayed right now is h:mm:ss a VV. My issue is if I swap my locale to zh_TW, it displays as 下午11:59 Asia/Shanghai.

I'd like to have the Asia/Shanghai part to be translated to the correct Locale as well. How would I do this?

I have tried using DateTimeFormatter.ofPattern("h:mm:ss a VV", locale) but the zone id (VV) part only shows in English.


Solution

  • my output needs to be Region/(City or Country)

    The two parts in time zone IDs like Asia/Shanghai are not supposed to be translated separately.

    You can however, get an "exemplar city" for a timezone. This is one of the many things that CLDR records. I am not aware of a standard Java API for getting the exemplar city, but you can use the CLDR engine library (Maven).

    Suppose I want to find an exemplar city of Asia/Shanghai localised for ar-BH.

    var cldr = CLDR.get("ar-BH");
    System.out.println(cldr.Schema.TimeZones.exemplarCity.get(cldr.General.bundle(), "Asia/Shanghai"));
    

    Output:

    شنغهاي 
    

    If you also want the localised name of the continent ("Asia" in Asia/Shanghai), you can use getRegionDisplayName.

    System.out.println(cldr.General.getRegionDisplayName("142", DisplayNameOptions.build()));
    

    Note that I passed "142", which is apparently the UN M49 ID for Asia. See the list of the available IDs here. There is only a small number of options for the part before the / in IANA zone names. It shouldn't be too difficult to maintain a mapping from "Asia" to "142", "Europe" to "150", etc.