I'm using Spring Boot with the following ObjectMapper:
@Bean
public ObjectMapper objectMapper()
{
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true)); // Makes no difference to output
mapper.findAndRegisterModules();
return mapper;
}
When OffsetDateTimes are serialized and returned in responses, they have a format like this:
"2020-02-28T12:28:29.01Z"
"2020-02-28T12:36:21.885Z"
I would have expected the timezone information at the end to look like this instead:
"2020-02-28T10:41:25.287+00:00"
Is there something I'm missing or doing wrong here, or anyway I can get the timezone information serialized as the +00:00
format instead of 885Z
format?
Many thanks!
The new Java 8 Time API provides a DateTimeFormatter
where you can set the end of the format to one or more x
or X
. As per the api description:
Offset X and x: This formats the offset based on the number of pattern letters. One letter outputs just the hour, such as '+01', unless the minute is non-zero in which case the minute is also output, such as '+0130'. Two letters outputs the hour and minute, without a colon, such as '+0130'. Three letters outputs the hour and minute, with a colon, such as '+01:30'. Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'. Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'. Six or more letters throws IllegalArgumentException. Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero, whereas pattern letter 'x' (lower case) will output '+00', '+0000', or '+00:00'.
So, in your case your formatting string should end in xxx
for +1:30
, e.g. "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"
with the SSS
always giving the milliseconds.
To use this DateTimeFormatter
with Jackson, you either need to define a custom serializer
public class DefaultZonedDateTimeSerializer extends JsonSerializer<ZonedDateTime> {
private static final DateTimeFormatter ISO_8601_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
.withZone(ZoneId.of("UTC"));
@Override
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value == null) {
throw new IOException("ZonedDateTime argument is null.");
}
gen.writeString(ISO_8601_FORMATTER.format(value));
}
and annotate the respective fields in your beans with
@JsonSerialize(using = DefaultZonedDateTimeSerializer.class)
private ZonedDateTime someTimeProperty;
or you need to convert from DateTimeFormatter
to DateFormat
(older, but used by Jackson) as described here: Using DateTimeFormatter with ObjectMapper
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