Issue
How to convert the value in the below input to the format of 9:15 pm, 2nd May 2023
Input: 2023-11-20T17:09:08.000Z
What I tried: I tried to use SimpleDateFormat, But I couldn't get the appropriate format
val curFormater = SimpleDateFormat("dd-MM-yyyy")
Any other attempts result in a parse error ... Is there a proper standard way to achieve this?
Solution
There is. As rzwitserloot already said, immediately ditch the obsolete SimplateDateFormat
. Use classes from the java.time
package instead.
Then you need to do the following:
1. Parse the string
to a proper date and time model. I picked OffsetDateTime
here, as your input string contains a date component, a time component and a time zone thingy (the Z
).
OffsetDateTime dateTime = OffsetDateTime.parse(input);
Since the input format is conform to the ISO 8601 standard, you don't have to specify a format; it will parse the string out-of-the-box.
2. Define the right output format
and you can use format
to form the desired text. This looks like it:
String output = dateTime.format(DateTimeFormatter.ofPattern("h:mm a, d MMMM uuuu", Locale.UK));
Ordinal suffix
But then there is a small problem. You are using an English ordinal suffix (st, nd, rd, th), and there is no such formatting pattern to output such. Fortunately, you can use a DateTimeFormatterBuilder
to have a more fine-grained control over the output. We can use appendText(Map<Long, String>)
to look up a value mapped to a certain comnponent field.
final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("h:mm a, d")
.appendText(ChronoField.DAY_OF_MONTH, ordinalSuffixes)
.appendPattern(" MMMM uuuu")
.toFormatter(Locale.UK);
This will use the day of the month as a long to lookup that specific value in the given map. So we will need to make sure that we have a map which returns the correct values for the correct keys.
Map<Long, String> ordinalSuffixes = IntStream.rangeClosed(1, 31)
.mapToObj(n -> Map.entry((long) n, switch (n) {
case 1, 21, 31 -> "st";
case 2, 22 -> "nd";
case 3, 23 -> "rd";
default -> "th";
}))
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));
Answered By - MC Emperor
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.