Use Built-in Joda Serializer/Deserializer for easy config
If you want custom formatting, there's no need to write a custom Serializer or Deserializer. jackson-datatype-joda
2.x provides a DateTimeSerializer
and DateTimeDeserializer
on which you can set a DateTimeFormatter
to use, providing you custom formatting. You then add the configured Serializer and/or Deserializer to the JodaModule
when you add the module.
An advantage of using the provided Serializer/Deserializer (over custom ones) is that you can annotated any DateTime
properties with @JsonFormat(pattern = ". . .")
to override the format you configure. The custom Serializers/Deserializers shown in most of the other answers (from the Jackson 1.x days) will not honor @JsonFormat
annotations. So if you have that one odd ball DateTime
value that needs a a different format, it is easily handled, as shown in the below examples.
In addition to the DateTimeSerializer
and DateTimeDeserializer
, there are others such as LocalDateSerializer
/LocalDateDeserializer
, PeriodSerializer
/PeriodDeserializer
, etc.
Examples
Below is a Java and a Kotlin example. You will need to add the following to your dependencies:
com.fasterxml.jackson.datatype:jackson-datatype-joda:{version}
The examples show setting a default custom format, and overriding that format on a per property basis via the @JsonFormat
annotation.
Java Example
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat;
import com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer;
import com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer;
import org.joda.time.DateTime;
import org.joda.time.ReadableInstant;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class JacksonJodaTimeJavaExample
{
private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ");
private static final JacksonJodaDateFormat JACKSON_JODA_DATE_FORMAT =
new JacksonJodaDateFormat(DATE_TIME_FORMATTER);
private static ObjectMapper mapper = createMapper();
private static ObjectMapper createMapper()
{
return JsonMapper
.builder()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.addModule(new JodaModule()
// If you do not want to customize the formatting, you can remove the next two lines
.addSerializer(new DateTimeSerializer(JACKSON_JODA_DATE_FORMAT))
.addDeserializer(ReadableInstant.class, new DateTimeDeserializer(ReadableInstant.class, JACKSON_JODA_DATE_FORMAT))
)
// Enable pretty printing for our example
.enable(SerializationFeature.INDENT_OUTPUT)
.build();
}
record Event(
DateTime startTime,
DateTime endTime,
@JsonFormat(pattern = "yyyy-MM-dd 'at' HH:mm:ss")
DateTime dateTimeInAlternateFormat
) {}
public static void main(String[] args) throws Exception
{
final DateTime now = DateTime.now();
Event event = new Event(now, now.plusHours(1), now);
String json = mapper.writeValueAsString(event);
System.out.println(json);
Event deserializedEvent = mapper.readValue(json, Event.class);
System.out.println(deserializedEvent);
}
}
Kotlin Example
import com.fasterxml.jackson.annotation.JsonFormat
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.datatype.joda.JodaModule
import com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat
import com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer
import com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer
import org.joda.time.DateTime
import org.joda.time.ReadableInstant
import org.joda.time.format.DateTimeFormat
object JacksonJodaTimeKotlinExample
{
private val DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ")
private val JACKSON_JODA_DATE_FORMAT = JacksonJodaDateFormat(DATE_TIME_FORMATTER)
private val mapper = createMapper()
private fun createMapper() =
JsonMapper
.builder()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.addModule(
// If you do not want to customize the formatting, you can remove the "apply" block
JodaModule().apply {
addSerializer(DateTimeSerializer(JACKSON_JODA_DATE_FORMAT))
addDeserializer(ReadableInstant::class.java, DateTimeDeserializer(ReadableInstant::class.java, JACKSON_JODA_DATE_FORMAT))
})
// Enable pretty printing for our example
.enable(SerializationFeature.INDENT_OUTPUT)
.build()
data class Event(
var startTime: DateTime? = null,
var endTime: DateTime? = null,
// If we want a DateTime in an alternate format, we can
@JsonFormat(pattern = "yyyy-MM-dd 'at' HH:mm:ss")
var dateTimeInAlternateFormat: DateTime? = null)
fun runExample()
{
val now = DateTime.now()
val event = Event(now, now.plusHours(1), now)
val json = mapper.writeValueAsString(event)
println(json)
val deserializedEvent = mapper.readValue(json, Event::class.java)
println(deserializedEvent)
}
}
fun main()
{
JacksonJodaTimeKotlinExample.runExample()
}