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
Sorting an Array of Int Using Bubblesort
Jtable Row Hightlighter Based on Value from Tablecell
Why Static Fields Are Not Initialized in Time
How to Load/Reference a File as a File Instance from the Classpath
Mocking Files in Java - Mock Contents - Mockito
How to Parse a JSON String to an Array Using Jackson
Difference Between Oracle Jdbc Driver Classes
What Does Maven Do, in Theory and in Practice? When Is It Worth to Use It
Why We Shouldn't Make a Spring MVC Controller @Transactional
How to Get the Current Date and Time of Your Timezone in Java
How to Show Jrbeancollectiondatasource Data with Help of Table Component