I need to format a Java java.time.LocalDateTime
into a JSON string that will match this format:
2023-09-17T00:00:00.000+00:00
I was looking at DateTimeFormatter.ISO_DATE_TIME
defining my LocalDateTime with:
date.plusDays(daysToAdd)
.atZone(ZoneOffset.UTC)
.format(DateTimeFormatter.ISO_DATE_TIME)
but that produces:
2023-09-17T00:00:00Z
Is there a predefined formatter for this date format? Do I need to create a custom DateTimeFormatter, if so could you provide an example for this format?
I ended up using a formatter based on Mark Rotteveel's example solution and the subsequent comments to this question:
val jsonDateTimeFormatter: DateTimeFormatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.appendPattern("HH:mm:ss.SSS")
.appendOffset("+HH:MM", "+00:00")
.toFormatter()
There is no standard formatter that gives the exact result you want. The use of Z
for offset 0 is standard (probably derives from ISO 8601, but I'm too lazy to verify).
For the format you want, you'll need to build it up (see first example), or use a pattern (see second example). My example is in Java, but I assume it will translate directly to Scala:
public static void main(String[] args) {
var date = LocalDateTime.parse("2023-09-17T00:00:00");
var fm = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.appendValue(HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2)
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.appendFraction(MILLI_OF_SECOND, 3, 3, true)
.appendOffset("+HH:MM", "+00:00")
.toFormatter();
System.out.println(date.atOffset(ZoneOffset.UTC).format(fm));
}
The most important parts here for your requirements are:
.appendFraction(MILLI_OF_SECOND, 3, 3, true)
Ensures the fractional seconds are rendered in 3 digits.
.appendOffset("+HH:MM", "+00:00")
Renders the offset as {+/-}HH:mm
(e.g. -01:00
), and offset 0 as +00:00
.
Output:
2023-09-17T00:00:00.000+00:00
You can also use a pattern-based formatter:
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxx")
The use of .SSS
ensures three fractional digits, and xxx
renders the offset as {+/-}HH:mm
and offset 0 as +00:00
.
Note that it is probably best to use either of these formatters for formatting dates only, and use ISO_DATE_TIME
for parsing, as it is more flexible and lenient.