application.yml
configuration:
jackson:
date-format: yyyy-MM-dd
timestamp-format:yyyy-MM-dd HH:mm:ss
serialization:
write-dates-as-timestamps: false
Bean properties:
@Entity
@Column(nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Temporal(TemporalType.DATE)
private Date date_created;
@Column(nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Temporal(TemporalType.TIMESTAMP)
private Date reg_date;
I set all Date
fields as java.util.Date
type which receive date in format yyyy-MM-dd
and timestamp type(yyyy-MM-dd HH:mm:ss
) according to request param style(yyyy-MM-dd
or yyyy-MM-dd HH:mm:ss
)
For using timestamp
, I found the @Temporal(TemporalType.Date
or Timestamp
) which is mapping by DB Type
.
Date and timestamp format is stored correctly like yyyy-MM-dd
or yyyy-MM-dd HH:mm:ss.sss
RestController
class:
@PostMapping("/")
public ResponseEntity<Object> create(@RequestBody CreateVO createVO, HttpServletRequest request) {
System.out.println("planned_date> "+createVO.getDate_planned_start());
System.out.println("regdate> "+createVO.getReg_date());
}
Are set to:
planned_date> Wed Mar 20 09:00:00 KST 2019 // Date Result
regdate> Mon Oct 01 16:45:00 KST 2012 //Timestamp Result
However, I receive in RestController Date
in different format than i expected.
Is there any solution to receive yyyy-MM-dd
and yyyy-MM-dd HH:mm:ss
in Controller
?
I am wondering about application.yml
settings as well. Because I am not sure how to set timestamp-format.
First of all Date.toString
method generates misleading output and we should not rely on it. Simple example:
SimpleDateFormat dateToStringFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", new Locale("us"));
Date parsed = dateToStringFormat.parse("Wed Mar 20 09:00:00 KST 2019");
System.out.println("Default toString: " + parsed);
dateToStringFormat.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));
System.out.println("With 'Asia/Seoul' TZ: " + dateToStringFormat.format(parsed));
dateToStringFormat.setTimeZone(TimeZone.getTimeZone("Chile/Continental"));
System.out.println("With 'Chile/Continental' TZ: " + dateToStringFormat.format(parsed));
prints:
Default toString: Wed Mar 20 01:00:00 CET 2019
With 'Asia/Seoul' TZ: Wed Mar 20 09:00:00 +0900 2019
With 'Chile/Continental' TZ: Tue Mar 19 21:00:00 -0300 2019
As you can see I parsed your example date Wed Mar 20 09:00:00 KST 2019
and print using toString
method and formatted with two different timezones. So, everyone sees date combined with his timezone. Read more about:
- Java Date toString contains a timezone… Why?
- Parsing a java Date back from toString()
We can not define date patters in configuration like you proposed. See available Jackson
configuration options here.
You can configure format using com.fasterxml.jackson.annotation.JsonFormat
annotation. Since Java 8
is available we should use java.time.*
classes for time related properties. Example POJO
class could like this:
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.MonthDay;
public class RequestPayload {
@JsonFormat(pattern = "MM/dd")
private MonthDay md;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime dateTime;
// getters, setters, toString
}
To make it work we need to register JavaTimeModule
module:
@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.modules(new JavaTimeModule());
return builder;
}
If you can change your Bean
properties to java.time.*
classes just propagate these dates from Controller
to DB
. In other case see this question: Converting between java.time.LocalDateTime and java.util.Date.