我面临的问题是,我需要将时间从24格式转换为AM/PM格式(反之亦然),并通过time4j库删除冗余值(如纳秒和秒)。

我正在使用time4j库,因为Java无法处理Windows时区,因此我必须通过time4j对其进行转换

从24小时格式到AM/PM的转换将取决于用户的本地化。我想将其(本地化)作为参数传递。本地化将看起来像“en-US”字符串。

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

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

有什么想法怎么做? (请帮助)

我必须花很多时间阅读time4j doc,但我的想法很震惊

要全面了解我在做什么以及所有这些目的是什么:

我必须从与Windows时区相对应的数据库中获取用户timeZone,并将其转换为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”是数据库中的timeZone。它对应于Microsoft Name of Time Zones

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

我确实是这样的:
PlainTime currentTime = SystemClock.inZonalView(winZone).now().toTime();
//currentTime: "T17:31:37,057"

“winZone”转换为timeZone的位置(例如“WINDOWS〜Europe/Kiev”)

现在回到我在帖子顶部描述的问题。
  • 也许最好在已经定义用户本地化时以所需的格式获取时间?
  • 如何将时间从24格式转换为AM/PM,反之亦然?
  • 如何删除多余的值,例如纳秒和秒?
  • 如何在转换中使用用户本地化?
  • 最佳答案

    这很简单,只要您知道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的format-API,因为PlainTime实现了JSR-310接口(interface)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以获得更多功能,更好的i18n和更高的性能。例如,如果使用不同的语言环境,则使用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
    

    10-06 12:58
    查看更多