如何将 24 小时制时间转换为 AM/PM 并通过 time4j 删除纳秒和秒?

How to convert time 24-hour to AM/PM and remove nanoseconds & seconds via time4j?

我遇到了一个问题,我需要将时间从 24 格式转换为 AM/PM 格式(反之亦然),通过 time4j 库删除冗余值,例如纳秒和秒。

我正在使用 time4j 库,因为 Java 无法处理 Windows 时区,我必须通过 time4j[=15 转换它们=]

从 24 小时格式转换为 AM/PM 将取决于用户本地化。我想把它(本地化)作为一个论点来传递。本地化看起来像 "en-US" 字符串。

例如: 如果用户本地化为 "en-US",则将 24 小时格式转换为 AM/PM。否则保持当前值。

或者当我已经定义了我的用户的本地化时,以我需要的格式获取时间可能更好?

有什么办法吗?请帮忙)

我不得不花很多时间阅读time4j doc,但我的思绪被吹走了

全面了解我正在做的事情以及这一切的目的:

我必须从我的数据库中获取与 Windows 时区对应的用户时区,并将它们转换为 IANA 时区。我已经用这种方法做到了

WindowsZone wzn = WindowsZone.of(userTimeZoneId); //userTimeZoneId="eg. FLE Standart Time"
TZID winZone = wzn.resolveSmart(new Locale("","001"));
System.out.println(winZone.canonical()); // WINDOWS~Europe/Kiev

其中 "userTimeZoneId" 是来自数据库的时区。对应于Microsoft Name of Time Zones

我的下一步是从我已经转换为 IANA 时区的用户时区获取时间/或时间戳。

我喜欢这个:

PlainTime currentTime = SystemClock.inZonalView(winZone).now().toTime(); 
//currentTime: "T17:31:37,057"

其中 "winZone" 转换时区(例如 "WINDOWS~Europe/Kiev")

所以现在回到我在 post 顶部描述的问题。

  1. 当我已经定义了用户的本地化时,也许以我需要的格式获取时间会更好?

  2. 如何将时间从 24 格式转换为 AM/PM,反之亦然?

  3. 如何去除纳秒、秒等冗余值?

  4. 如何在转换中使用用户本地化?

这很简单,只要您知道 Time4J 中的专用格式化程序 API 基于 ChronoFormatter:

Locale ukraine = new Locale("en", "UA"); // or use new Locale("en", "001") for worldwide
TZID winZone = WindowsZone.of("FLE Standard Time").resolveSmart(ukraine);
PlainTime currentTime = SystemClock.inZonalView(winZone).now().toTime();
System.out.println(currentTime); // T12:02:40,344

// truncate seconds and nanoseconds
currentTime = currentTime.with(PlainTime.PRECISION, ClockUnit.MINUTES);
System.out.println(currentTime); // T12:02

// format in am/pm-notation
ChronoFormatter<PlainTime> f1 =
    ChronoFormatter.ofTimePattern("h:mm a", PatternType.CLDR, Locale.US);
String formatted1 = f1.format(currentTime);
System.out.println(formatted1); // 12:02 pm

// or use styled formatter (which has only limited control over displayed precision)
ChronoFormatter<PlainTime> f2 = 
    ChronoFormatter.ofTimeStyle(DisplayMode.SHORT, Locale.US);
String formatted2 = f2.format(currentTime);
System.out.println(formatted2); // 12:02 pm

如果您想让语言环境控制格式模式,则基于样式的解决方案(如上面针对 Time4J 所演示的)是合适的。例如,德语语言环境将打印“12:02”而不是“12:02 pm”(美国)。

顺便说一句,如果您愿意,您也可以自由使用 java.time 的格式-API,因为 PlainTime 实现了 JSR-310 接口TemporalAccessor:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:mm a", Locale.US);
System.out.println(dtf.format(currentTime)); // 12:02 PM

此处大小写不同是因为 JDK(至少在我的系统上)仍然使用旧的 CLDR 数据进行国际化,而 Time4J 拥有自己的基于实际 CLDR 版本 v33 的资源。 A future Java version will surely change the capitalization。总的来说,我还是推荐使用 ChronoFormatter 来获得更多的特性、更好的国际化和更高的性能。例如,如果您使用不同的语言环境,使用 Time4J 解析 am/pm-literals 的反向方法比在 java.time 中更可靠。

如果您想将 "AM" 和 "PM" 以大写字母(或任何其他自定义格式)与 ChronoFormatter 一起使用,那么您还可以使用:

Map<Meridiem, String> map = new EnumMap<>(Meridiem.class);
map.put(Meridiem.AM, "AM");
map.put(Meridiem.PM, "PM");
ChronoFormatter<PlainTime> f3 =
    ChronoFormatter
        .setUp(PlainTime.axis(), Locale.ROOT)
        .addPattern("h:mm ", PatternType.CLDR)
        .addText(PlainTime.AM_PM_OF_DAY, map)
        .build();
String formatted3 = f3.format(currentTime);
System.out.println(formatted3); // 12:02 PM