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

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

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

Преобразование из 24-часового формата в AM/PM будет зависеть от локализации пользователей. И я хочу передать его (локализацию) в качестве аргумента. Локализация будет выглядеть как строка "en-US".

Например: если локализация пользователей "en-US", то конвертируйте 24-часовой формат в AM/PM. Остальное сохраняйте текущее значение.

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

Есть идеи, как это сделать? Пожалуйста помоги)

Я должен тратить много времени на чтение документа time4j, но мой ум просто потрясен

Чтобы иметь полную шкалу того, что я делаю и для чего все это нужно:

Я должен получить timeZone пользователей из моей БД, которая соответствует часовым поясам 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" - это timeZone из БД. Это соответствует Microsoft Название часовых поясов

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

Я сделал это так:

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

Где "winZone" конвертирует timeZone (например, "WINDOWS~Europe/Kiev")

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

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

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

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

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

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-literal более надежен при использовании 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
Другие вопросы по тегам