MenoData / Time4J

Advanced date, time and interval library for Java with sun/moon-astronomy and calendars like Chinese, Coptic, Ethiopian, French Republican, Hebrew, Hijri, Historic Christian, Indian National, Japanese, Julian, Korean, Minguo, Persian, Thai, Vietnamese
GNU Lesser General Public License v2.1
424 stars 62 forks source link

Localize absolute datetimes #932

Closed s5bug closed 3 years ago

s5bug commented 3 years ago

ICU4J has this feature where datetimes will be printed as Sunday, December 27, 2020 at 12:59:39 PM Pacific Standard Time in en_US but as 2020年12月27日日曜日 12時42分05秒 アメリカ太平洋標準時 in ja_JP. I'd like to be able to use this but fully in the Java 8 time API (I'd like to be able to drop ICU4J from my project).

Is this something that is in scope of Time4J? If not, where should I look?

s5bug commented 3 years ago

Tried another long bit of Googling and eventually found java.time.format.DateTimeFormatter.

ZonedDateTime then = ZonedDateTime.now(rtz);
DateTimeFormatter formatter =
    DateTimeFormatter
        .ofLocalizedDateTime(FormatStyle.FULL)
        .withLocale(rlocale)
        .withZone(rtz);
String result = formatter.format(then);
MenoData commented 3 years ago

I am not sure why you posted an issue for looking for a java.time-solution on this website. But for completeness, I give an answer using Time4J:

    Timezone california = Timezone.of("America/Los_Angeles");
    ChronoFormatter<Moment> f =
        ChronoFormatter.ofMomentStyle(DisplayMode.FULL, DisplayMode.FULL, Locale.US, california.getID());

    Moment m = PlainTimestamp.of(2020, 12, 27, 12, 59, 39).in(california);

    System.out.println(f.print(m)); // "Sunday, December 27, 2020 at 12:59:39 pm Pacific Standard Time"
    System.out.println(f.with(Locale.JAPAN).print(m)); // "2020年12月27日日曜日 12時59分39秒 太平洋標準時"

In contrast to your ICU4J-version, Time4J uses small letters for PM corresponding to the newest CLDR repository version. Furthermore, the Katakana writing of "Pacific Standard Time" is replaced by the Kanji writing. I think both is correct.

About your java.time-code, well, it might hopefully do what you wish. However, on my Java-8-platform (I know little bit old), your code produces: 2020年12月27日 12時59分39秒 PST No weekday, and English zone name (PST). I hope for you newer Java versions are better here.

s5bug commented 3 years ago

Ah! I had the wrong idea about java.time being used with Time4J: I thought that Time4J was supposed to "fill in the gaps" per-say. Your example makes a lot more sense, and I think it's what I actually want.

What would be the equivalent of ZonedDateTime.now(timezone)?

MenoData commented 3 years ago

Sorry for late reply:

a) Time4J can be used either as replacement or as supplement to java.time (for missing features). The first approach only uses conversions where external API interfaces enforce the conversion while the supplement case probably involves more conversions. Personally, I prefer to use Time4J as widely as possible.

b) The equivalent of ZonedDateTime.now(timezone) assuming the type ZoneId for the parameter timezone would be: ZonedDateTime zdt = Moment.nowInSystemTime().inZonalView(timezone.getId()).toTemporalAccessor(). Personally, I would rather avoid the use of ZonedDateTime and simply use Moment.nowInSystemTime() and the formatting example in my previous answer. Or if I need to convert Moment to a local type then I would go this way: PlainTimestamp tsp = moment.toZonalTimestamp(timezone.getId()).

c) A good overview for getting conversions between java.time and Time4J is available in the documentation of the class TemporalType.