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.
Maybe it's better to get time in the format I need when I already define localization of my user?
How can I convert time from 24 format to AM/PM and vise-versa?
How to remove redundant values such as nanoseconds and seconds?
How can I use user localization in conversion?
"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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With