Как преобразовать 24-часовое время в AM/PM и удалить наносекунды и секунды через time4j?

Я столкнулся с проблемой, что мне нужно преобразовать время из формата 24 в формат AM/PM (и наоборот), удалив избыточные значения, такие как наносекунды и секунды, с помощью библиотеки time4j.

Я использую библиотеку time4j, поскольку Java не поддерживает часовые пояса Windows, и мне приходится преобразовывать их с помощью time4j

Преобразование из 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

Мой следующий шаг — получить отметку времени/времени из часового пояса пользователей, который я уже преобразовал в часовые пояса IANA.

Я сделал так:

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

Где "winZone" преобразует часовой пояс (например, "WINDOWS~Европа/Киев")

Итак, возвращаясь к моей проблеме, которую я описал в начале поста.

  1. Может лучше получить время в нужном мне формате, когда я уже определил локализацию своего пользователя?

  2. Как преобразовать время из формата 24 в формат AM/PM и наоборот?

  3. Как удалить избыточные значения, такие как наносекунды и секунды?

  4. Как я могу использовать локализацию пользователя в конверсии?


person Roman Shabanov    schedule 15.06.2018    source источник


Ответы (1)


Это несложно, если вы знаете, что специальный API форматирования в Time4J основан на 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» (США).

Кстати, вы также можете использовать API формата java.time, если хотите, потому что 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. В будущих версиях Java заглавные буквы наверняка будут изменены. В общем, я все же рекомендую использовать ChronoFormatter ради большего количества возможностей, лучшего i18n и большей производительности. Например, обратный способ парсинга am/pm-литералов более надежен при использовании Time4J, чем в 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
person Meno Hochschild    schedule 16.06.2018
comment
Спасибо, мужик! Вы мне очень помогаете) Работает! Небольшие модификации и адаптация помогут мне сделать методы более гибкими) - person Roman Shabanov; 18.06.2018