Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm faced with the issue that I need to convert time from 24 format to AM/PM format (and vice-versa) removing redundant values such as nanoseconds and seconds by time4j library.

I'm using the time4j library because Java can't handle Windows Time Zones and I have to convert them via time4j

Conversion from 24 hour format to AM/PM will depend on users localization. And I want to transmit it (localization) as an argument. Localization will look like "en-US" string.

For example: If users localization is "en-US" then convert 24 hour format to AM/PM. Else keep current value.

Or maybe it's better to get time in the format I need when I already define localization of my user?

Any ideas how to do this? Please help)

I have to spend a lot of time reading time4j doc but my mind is blown

To have full scale of what I'm doing and what the purpose all of this:

I have to get users timeZone from my DB which corresponds to Windows Time Zones and convert them to IANA time zones. I already did this by this method

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

Where "userTimeZoneId" is timeZone from DB. It corresponds to Microsoft Name of Time Zones

My next step is to get time / or time stamp from users time zone which I already convert to IANA time zones.

I did like this:

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

Where "winZone" converted timeZone (eg. "WINDOWS~Europe/Kiev")

So now returning to my problem I described at the top of the post.

  1. Maybe it's better to get time in the format I need when I already define localization of my user?

  2. How can I convert time from 24 format to AM/PM and vise-versa?

  3. How to remove redundant values such as nanoseconds and seconds?

  4. How can I use user localization in conversion?

like image 666
Roman Shabanov Avatar asked Jun 15 '18 12:06

Roman Shabanov


People also ask

How do you convert 24 hour to am pm?

"AM" stands for "ante meridiem" which means "before noon" while PM stands for "post meridiem" which means "after noon." Include the signifier "AM" for times between 1:00 and 11:59. Since 24-hour times moves from 00:00 (midnight) to 1:00, all you have to do is add "AM" to the time from 1:00 up until 11:59.

How do you convert 24 hours to am?

Starting from the first hour of the day (12:00 AM or midnight to 12:59 AM), subtract 12 hours: 12:00 AM = 0:00.

How do you convert time from am to pm?

From 0:00 (midnight) to 0:59, add 12 hours and use am. From 1:00 to 11:59, just add am after the time. From 12:00 to 12:59, just add pm after the time. From 13:00 to 0:00, subtract 12 hours and use pm.

How do you convert 24 hrs to 12 hours in react native?

function tConvert (time) { // Check correct time format and split into components time = time. toString (). match (/^([01]\d|2[0-3])(:)([0-5]\d)(:[0-5]\d)? $/) || [time]; if (time.


1 Answers

This is straight forward as long as you know that the dedicated formatter API in Time4J is based on 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

A style-based solution (as demonstrated above for Time4J) is appropriate if you want to let the locale control the format pattern. For example, a german locale would print "12:02" instead of "12:02 pm" (US).

By the way, you are also free to use the format-API of java.time if you want because PlainTime implements the JSR-310-interface TemporalAccessor:

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

Here the different capitalization originates from the fact that the JDK (at least on my system) still uses older CLDR-data for internationalization while Time4J has its own resources based on actual CLDR-version v33. A future Java version will surely change the capitalization. In general, I still recommend to use ChronoFormatter for sake of more features, better i18n and more performance. For example, the reverse way of parsing am/pm-literals is more reliable using Time4J than in java.time if you work with different locales.

If you like to use "AM" and "PM" in capitalized letters (or any other customized format) together with ChronoFormatter then you can also use:

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
like image 65
Meno Hochschild Avatar answered Oct 03 '22 13:10

Meno Hochschild