
LocalDateTime + TimeZone 합쳐진 방식입니다.
ZonedDateTime = LocalDate + LocalTime + ZoneOffset + ZoneRegion
ZonedDateTime 객체를 생성할 때는, now나 of의 정적 메소드를 통해 생성합니다.
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime nowSeoul = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
ZonedDateTime birthday = ZonedDateTime.of(2000, 1, 1, 0, 0, ZoneId.of("Asia/Seoul"));
Now in Seoul is 2023-08-07T00:15:12.862+09:00[Asia/Seoul]
Now in Seoul is 2023-08-07T00:15:12.862+09:00[Asia/Seoul]
birthday is 2000-01-01T20:30+09:00[Asia/Seoul]
ZoneId는 타임존, ZoneOffSet은 시차를 나타냅니다.
ZoneOffSet은 UTC 기준으로 시간 차이를 양수나 음수로 나타내고,
ZoneId는 해당 시간 차이를 타임존 코드로 나타냅니다.
예를 들어 서울의 경우, 타임존 코드는 Asia/Seoul 시차는 +09:00 입니다.
ZoneOffset seoulZoneOffset = ZoneOffset.of("+09:00");
System.out.println("+09:00 Time = " + ZonedDateTime.now(seoulZoneOffset));
ZoneId seoulZoneId = ZoneId.of("Asia/Seoul");
System.out.println("Seoul Time = " + ZonedDateTime.now(seoulZoneId));
+09:00 Time = 2023-08-07T11:16:47.261+09:00
Seoul Time = 2023-08-07T11:16:47.261+09:00[Asia/Seoul]
문자열을 ZonedDateTime 변환하기 위해서는 ZonedDateTime.parse() 메소드를 사용합니다.
ZonedDateTime zdt1 = ZonedDateTime.parse("2002-06-18T20:30:00+09:00[Asia/Seoul]");
ZonedDateTime zdt2 = ZonedDateTime.parse("2002/06/18/ 20:30:00 KST", DateTimeFormatter.ofPattern("yyyy/MM/dd/ HH:mm:ss z"));
Spring Data JPA 에서는 Auditing 기능을 제공합니다.
엔터티 생성되고 변경되는 시점을 Audit(감지)하여,
엔터티의 생성 시각, 수정 시각을 기록합니다.
@EnableJPAAuditing
@EnableJPAAuditing 어노테이션을 사용하여,
Auditing 을 활성화 해야합니다.
@EnableJPAAuditing
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
}
Post Entity
@Getter
@NoArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
private String content;
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@EntityListeners
Auditing을 적용할 엔터티 클래스에 @EntityListeners 어노테이션을 적용합니다. 그러면 엔터티의 변화를 감지하여 매핑된 테이블의 데이터를 조작합니다.
이벤트 리스너로는AuditingEntityListener 클래스를 넣어줍니다.
해당 클래스는 Spring Data JPA에서 제공하는 이벤트 리스너로 엔터티의 영속, 수정 이벤트를 감지하는 역할을 합니다.
@CreateDate
생성일을 기록하기 위해 LocalDateTime 타입의 필드에 @CreatedDate 를 적용합니다.
또한 생성 일자의 수정을 막기 위해 @Column(updatable=false) 를 적용합니다.
이 후에는 엔터티가 생성됨을 감지하고 그 시점을 createdAt 필드에 기록합니다.
Spring Data JPA 에서 사용하는
@CreatedDate, @LastModifiedDate 는
ZonedDateTime 을 지원하지 않습니다.
ZonedDateTime 타입의 형태로 AuditingEntityListener 를 이용하여
시간을 기록하려고 할 때 에러가 발생합니다.
Supported types are [org.joda.time.DateTime, org.joda.time.LocalDateTime, java.util.Date, java.lang.Long, long].; nested exception is java.lang.IllegalArgumentException:
@PrePersist / @PreUpdate
ZonedDateTime의 경우에는
JPA Entity의 라이프 사이클(생명 주기)을 관리하는 어노테이션을 이용합니다.
@PrePersist : persist() 메소드를 호출해서 엔티티를 영속성 컨텍스트에 관리하기 직전에 호출된다.
@PreUpdate : flush나 commit을 호출해서 엔티티를 데이터베이스에 수정하기 직전에 호출된다.
@Entity
public class Post {
@Column(name = "created_at")
private ZonedDateTime createdAt;
@Column(name = "updated_at")
private ZonedDateTime updatedAt;
@PrePersist
public void onPrePersist() {
this.createdAt = ZonedDateTime.now();
this.updatedAt = ZonedDateTime.now();
}
@PreUpdate
public void onPreUpdate() {
this.updatedAt = ZonedDateTime.now();
}
}