JSON Serializing date in a custom format (Can not construct instance of java.util.Date from String value)
Asked Answered
W

7

30
could not read JSON: Can not construct instance of java.util.Date from String 
value '2012-07-21 12:11:12': not a valid representation("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))

passing json request to REST controller method in a POJO class.user should enter only in below datetime format other wise it should throw message.why DateSerializer is not calling?

add(@Valid @RequestBody User user)
{
}

json:

{
   "name":"ssss",
   "created_date": "2012-07-21 12:11:12"
}

pojo class variable

@JsonSerialize(using=DateSerializer.class)
@Column
@NotNull(message="Please enter a date")      
@Temporal(value=TemporalType.TIMESTAMP)
private Date created_date;

public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
    logger.info("serialize:"+value);
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    logger.info("DateSerializer formatter:"+formatter.format(value));
    jgen.writeString(formatter.format(value));
}
Westnorthwest answered 15/7, 2013 at 13:33 Comment(0)
F
21

I have the same problem, so I write a custom date deserialization with @JsonDeserialize(using=CustomerDateAndTimeDeserialize.class)

public class CustomerDateAndTimeDeserialize extends JsonDeserializer<Date> {

    private SimpleDateFormat dateFormat = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    @Override
    public Date deserialize(JsonParser paramJsonParser,
            DeserializationContext paramDeserializationContext)
            throws IOException, JsonProcessingException {
        String str = paramJsonParser.getText().trim();
        try {
            return dateFormat.parse(str);
        } catch (ParseException e) {
            // Handle exception here
        }
        return paramDeserializationContext.parseDate(str);
    }
}
Forbore answered 19/11, 2014 at 2:27 Comment(1)
How are you implementing this CustomerDateAndTimeDeserialize class?Tifanytiff
G
54

Annotate your created_date field with the JsonFormat annotation to specify the output format.

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = TimeZone.getDefault(), locale = Locale.getDefault())

Note that you may need to pass in a different Locale and TimeZone if they should be based on something other than what the server uses.

You can find out more information in the docs.

Gimbals answered 25/11, 2014 at 16:12 Comment(5)
Is it all you have to do? I tried this and it didn't work by itself. Maybe some other annotations are required somewhere?Selvage
You need to be using Jackson: fasterxml.github.io/jackson-annotations/javadoc/2.0.0/com/…Gimbals
Be aware of using this annotation. Here is known issue with with one day less.Dow
Don't forget to add timezone = "Canonical_ID_of_your_timezone" parameter after "pattern" if you want to have a right time. Timezones names could be found here: joda-time.sourceforge.net/timezones.htmlShelbyshelden
Or use: @Pattern(regexp = Constants.REGEX)Radicalism
F
21

I have the same problem, so I write a custom date deserialization with @JsonDeserialize(using=CustomerDateAndTimeDeserialize.class)

public class CustomerDateAndTimeDeserialize extends JsonDeserializer<Date> {

    private SimpleDateFormat dateFormat = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    @Override
    public Date deserialize(JsonParser paramJsonParser,
            DeserializationContext paramDeserializationContext)
            throws IOException, JsonProcessingException {
        String str = paramJsonParser.getText().trim();
        try {
            return dateFormat.parse(str);
        } catch (ParseException e) {
            // Handle exception here
        }
        return paramDeserializationContext.parseDate(str);
    }
}
Forbore answered 19/11, 2014 at 2:27 Comment(1)
How are you implementing this CustomerDateAndTimeDeserialize class?Tifanytiff
F
2

For someone ,If you are using DTO/VO/POJO to map your request you can simply annotate your date field

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

And json request should be:

{
"someDate":"2020-04-04 16:11:02"
}

You don't need to annotate Entity class variable.

Factotum answered 4/4, 2020 at 11:14 Comment(1)
what if date is blank?Alarise
D
1
  1. If you want to bind a JSON string to date, this process is called deserialization, not serialization.
  2. To bind a JSON string to date, create a custom date deserialization, annotate created_date or its setter with

    @JsonDeserialize(using=YourCustomDateDeserializer.class)

where you have to implement the method public Date deserialize(...) to tell Jackson how to convert a string to a date.

Enjoy.

Douglas answered 17/8, 2013 at 10:55 Comment(0)
S
0

Yet another way is to have a custom Date object which takes care of its own serialization.

While I don't really think extending simple objects like Date, Long, etc. is a good practice, in this particular case it makes the code easily readable, has a single point where the format is defined and is rather more than less compatible with normal Date object.

public class CustomFormatDate extends Date {

    private DateFormat myDateFormat = ...; // your date format

    public CustomFormatDate() {
        super();
    }

    public CustomFormatDate(long date) {
        super(date);
    }

    public CustomFormatDate(Date date) {
        super(date.getTime());
    }


    @JsonCreator
    public static CustomFormatDate forValue(String value) {
        try {
            return new CustomFormatDate(myDateFormat.parse(value));
        } catch (ParseException e) {
            return null;
        }
    }

    @JsonValue
    public String toValue() {
        return myDateFormat.format(this);
    }

    @Override
    public String toString() {
        return toValue();
    }
}
Selvage answered 26/3, 2015 at 11:17 Comment(0)
M
0

I solved this by using the below steps.

1.In entity class annote it using @JsonDeserialize

@Entity
@Table(name="table")
public class Table implements Serializable {
// Some code
@JsonDeserialize(using= CustomerDateAndTimeDeserialize.class)
@Temporal(TemporalType.TIMESTAMP)
@Column(name="created_ts")
private Date createdTs
}
  1. Write CustomDateAndTimeDeserialize.java Sample Code
Moonlighting answered 26/5, 2019 at 9:25 Comment(0)
K
0

I needed to annotate with the @JsonFormat and afterwards, this is working well:

@Temporal(TemporalType.DATE)
@DateTimeFormat(pattern = "MM-dd-yyyy")
@JsonFormat(pattern = "MM-dd-yyyy")
private java.util.Date expDate;
Katharyn answered 14/11, 2021 at 6:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.