How to Deserialize Js Date Using Jackson

How to deserialize JS date using Jackson?

I found a work around but with this I'll need to annotate each date's setter throughout the project. Is there a way in which I can specify the format while creating the ObjectMapper?

Here's what I did:

public class CustomJsonDateDeserializer extends JsonDeserializer<Date>
{
@Override
public Date deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException, JsonProcessingException {

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String date = jsonParser.getText();
try {
return format.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}

}

}

And annotated each Date field's setter method with this:

@JsonDeserialize(using = CustomJsonDateDeserializer.class)

Deserialize Date object with Jackson in Spring boot

the only global setting that worked for me is ObjectMapper

   @Bean
@Primary
public ObjectMapper objectMapper()
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
final ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(sdf);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
return mapper;
}

How to serialize/deserialize an ASP.NET JSON date using Jackson?

Your best bet is to write a custom deserializer. Or alternatively, to store the string representation of the date in your bean, but provide an alternative getter that converts the string to a date using a DateFormat instance. The first option is cleaner and more efficient.

See question previously asked here on SO.

Jackson serialize and Deserialize DateTime From/To WCF DateTime

To handle date time in format generated by .NET's JavaScriptSerializer in form /Date(number of ticks)/ you need to implement custom deserialiser. To understand what are "ticks" lets take a look at documentation:

Date object, represented in JSON as "/Date(number of ticks)/". The
number of ticks is a positive or negative long value that indicates
the number of ticks (milliseconds) that have elapsed since midnight 01
January, 1970 UTC.

The maximum supported date value is MaxValue (12/31/9999 11:59:59 PM)
and the minimum supported date value is MinValue (1/1/0001 12:00:00
AM).

I assume, that in your case you have an offset provided as well, like in examples.

Using Java 8 Time package and above knowledge we can implement custom deserialiser as below plus example usage:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import java.io.IOException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JsonPathApp {

public static void main(String[] args) throws Exception {
String inputJson = "{\"date\":\"/Date(1583001930882+0100)/\"}";

ObjectMapper mapper = new ObjectMapper();
Epoch epoch = mapper.readValue(inputJson, Epoch.class);
System.out.println(epoch.getDate());
}
}

class Epoch {

@JsonDeserialize(using = JavaScriptDateDeserializer.class)
private OffsetDateTime date;

public OffsetDateTime getDate() {
return date;
}

public void setDate(OffsetDateTime date) {
this.date = date;
}
}

class JavaScriptDateDeserializer extends JsonDeserializer<OffsetDateTime> {

private final Pattern JAVASCRIPT_DATE = Pattern.compile("/Date\\((-?\\d+)([+-]\\d+)\\)/");

@Override
public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getValueAsString();
Matcher matcher = JAVASCRIPT_DATE.matcher(value);
if (matcher.matches()) {
String epoch = matcher.group(1);
String offset = matcher.group(2);

Instant instant = Instant.ofEpochMilli(Long.parseLong(epoch));

return OffsetDateTime.ofInstant(instant, ZoneOffset.of(offset));
}

return null;
}
}

Above code prints:

2020-02-29T19:45:30.882+01:00

Serialiser could look like below:

class JavaScriptDateSerializer extends JsonSerializer<OffsetDateTime> {

@Override
public void serialize(OffsetDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
StringBuilder builder = new StringBuilder(32);
builder.append("/Date(");
builder.append(value.toInstant().toEpochMilli());
if (!value.getOffset().equals(ZoneOffset.UTC)) {
builder.append(value.getOffset().toString());
}
builder.append(")/");

gen.writeString(builder.toString());
}
}

You need to handle Time Zone properly, if you always send/receive date in UTC you can skip this part.

See also:

  • WCF and JSON Date format
  • JavaScript's Date
  • Unix epoch time to Java Date object
  • javascriptserializer date format issue
  • Good (Date)Times with Json.NET
  • C# DateTime.Ticks equivalent in Java

Jackson can't deserialize date set from Golang Api

The Go code you provided will not impact the way how the Time instance will be serialized as you are parsing it back into Time after serializing it to a string.

If you have control over how your date fields are serialized, you can apply the following format that should be aligned with what you provided to Jackson's ObjectMapper:

now := time.Now()
formattedDate := now.Format("2006-01-02T15:04:05.000Z0700")

If you don't have control over how the date is serialized on the Go side, you could also adjust the date format on the Java side. The following example assumes that time.RFC3339 is used by Go:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

Jackson JSON how to deserialize date from object-array

Read up on Polymorphic Deserialization. Currently all you're telling Jackson is that you want it to deserialize an array of Objects. In order for this to work, you need to annotate your MyDate class (or use Annotation Mixins to annotate the built-in Date class) so Jackson will output some additional type info when serializing your date. When deserializing, Jackson will use the that info to know what kind of class the JSON object represents.

How can I make Jackson deserialize a Long to a Date Object?

You want to use org.codehaus.jackson.map.JsonDeserializer and write the custom deserialization code. Something like:

public class DateDeserializer extends JsonDeserializer<Long> {
@Override
public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
... custom logic
}
}

I guess you have to figure out when a Long property has to be deserialized to Date. Maybe using annotations on your pojos?

Jackson date deserialization wrong

You have the incorrect datetime pattern. The pattern should be yyyyMMdd hhmmss.

'D' for Day in year and 'd' for Day in month.



Related Topics



Leave a reply



Submit