Explain Codes LogoExplain Codes Logo

Date Format Mapping to JSON Jackson

java
date-formatting
jackson
custom-serialization
Anton ShumikhinbyAnton Shumikhin·Oct 15, 2024
TLDR

You can command Jackson to serialize Date fields in a precise string format in JSON using @JsonFormat with pattern in your model class.

Example:

public class Event { // No need for a calendar when you have @JsonFormat! @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date eventDate; // getters and setters }

This small trick powers Jackson to format dates as "yyyy-MM-dd HH:mm:ss" in your JSON output.

Dealing with Timezones

At times, to fit your need, you might want to set your desired timezone with the timezone attribute:

// Goodbye confusion, hello `timezone`! @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "EST") private Date eventTime;

Custom Serialization/Deserialization

In intricate date formatting scenarios, you can rise above by creating custom serializers and deserializers. This bespoke approach paves the way to having full control over how dates are processed before being mapped to object members.

// Because 'Simple' in SimpleDateFormat is for 'brain-fryingly intricate' public class CustomDateSerializer extends StdSerializer<Date> { private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm a z"); public CustomDateSerializer() { this(null); } public CustomDateSerializer(Class<Date> t) { super(t); } @Override public void serialize(Date value, JsonGenerator gen, SerializerProvider arg2) throws IOException { gen.writeString(formatter.format(value)); } }

Tip: Hook your custom serializer class with @JsonSerialize annotation:

@JsonSerialize(using = CustomDateSerializer.class) private Date eventDate;

Pro tip: For deserialization, JsonDeserializer comes to the rescue:

// Deserializing dates, or desecrating daisies? public class CustomDateDeserializer extends StdDeserializer<Date> { public CustomDateDeserializer() { this(null); } public CustomDateDeserializer(Class<?> vc) { super(vc); } @Override public Date deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException { String date = jsonParser.getText(); try { return new SimpleDateFormat("yyyy-MM-dd HH:mm a z").parse(date); } catch (ParseException e) { throw new RuntimeException(e); } } }

Boldly integrate your deserializer using @JsonDeserialize:

@JsonDeserialize(using = CustomDateDeserializer.class) private Date eventDate;

Global Date Format: For the Greater Good

For times when you prefer to wield global power, conflict the ObjectMapper:

// You want global changes? Apply here ObjectMapper mapper = new ObjectMapper(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); mapper.setDateFormat(sdf);

This paragon now sets the standard date format for all Date serialization and deserialization processes in your domain.

Visualization

Let's put on our goggles and visualize custom date formatting in Java with Jackson as a journey through time:

🕒 Journey Through Time 🕒 | Present (Data Input) | Time Machine Settings (Annotation) | Future (JSON Output) | | -------------------- | ---------------------------------- | -------------------- | | 2023-04-12T08:30 | @JsonFormat(pattern="dd/MM/yyyy HH:mm:ss") | "12/04/2023 08:30:00" |

The Time Machine Settings (annotation) are the flux capacitor of our time machine, transforming the present into the future.

In Java:

@JsonFormat(pattern="dd/MM/yyyy HH:mm:ss") private Date startTime;

In JSON:

{ "startTime": "12/04/2023 08:30:00" }

Travelling through time with Jackson: You're not just coding, you're timelording!