복붙노트

[SPRING] 봄 REST LocalDate UTC는 하루 중 하나와 다릅니다.

SPRING

봄 REST LocalDate UTC는 하루 중 하나와 다릅니다.

저는 Spring Boot 1.5.4, Hibernate 5.2.10, Spring Data REST, HATEOAS, JDK8 LocalDate와 LocalDateTime을 사용하고 있습니다. 내 컴퓨터가 CEST 표준 시간대에 있지만 응용 프로그램이 UTC로 작동하기를 원하므로 application.properties에서 설정합니다.

spring.datasource.url=jdbc:mysql://localhost:3306/database?useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=true
spring.jpa.hibernate.jdbc.time_zone = UTC

이 기사에 따르면, JVM의 표준 시간대를 변경하고 싶지 않은 것은 모범 사례가 아니기 때문입니다.

Spring Data REST는 내 리포지토리를 공개하고 Swagger2를 사용하여 API를 사용할 수있는 멋진 인터페이스를 제공합니다. 끝점을 시도 할 때 다음과 같은 메시지가 표시됩니다.

    {
  "_embedded": {
    "dailyCodes": [
      {
        "sid": "d495cdaa-14f2-44cb-a98f-8aa6ddd43d91",
        "createdDate": "2017-06-28T16:20:01",
        "lastModifiedDate": "2017-06-28T16:20:01",
        "lastModifiedBy": "admin",
        "date": "2017-06-28",
        "code": "js",
        "new": false,
        "_links": {
          "self": {
            "href": "http://localhost:8080/api/v1/dailyCodes/1"
          },
          "dailyCode": {
            "href": "http://localhost:8080/api/v1/dailyCodes/1"
          }
        }
      }

마찬가지로 당신은 datetime 형식이 괜찮아요 또한 실시간으로 시간이 14시 20 분 01에있는 경우에도 CEST 시간을 표시 볼 수 있습니다. 내 REST API가 UTC에서 작동해야하기 때문에 이것이 잘못된 것 같습니다.

어떻게하면이 결과를 얻을 수 있습니까?

항상 같은 주제로, 나는 Spring Data REST에 의해 노출 된 REST 엔드 포인트를 가지고 LocalDate 매개 변수를 사용하여 검색했다. 나는 사용하고있다.

@Transactional
@PreAuthorize("isAuthenticated()")
public interface DailyCodeRepository extends PagingAndSortingRepository<DailyCode, Long> {

@Query("SELECT d FROM DailyCode d WHERE (:code IS NULL or code=:code) AND (:from IS NULL OR date>=:from) AND (:to IS NULL OR date<=:to)")
    public Page<DailyCode> findAllWithParameter(@Param("code") @RequestParam(value = "code", required = false) String code,
            @Param("from") @RequestParam(value = "from", required = false) LocalDate from,
            @Param("to") @RequestParam(value = "to", required = false) LocalDate to, Pageable pageable);
}

또한이 경우에는 이상한 점이 있습니다. 매개 변수를 전달하는 끝점을 호출하면 서버에서 1 일 이내에 도착합니다. 필자가 받아 들인 날짜 패턴은 내 로케일 (이탈리아어)의 JDK 기본값 인 것 같지만 모범 사례는 아닙니다.

양방향으로 날짜 / 시간 인수에 문제가 발생하지 않도록하기 위해 따라야 할 모범 사례가 있습니까?

해결법

  1. ==============================

    1.나는이 기사의 저자와 동의한다. 우리가 저장하고 UTC로 시간을 반환해야하는 API 날짜와 시간의 5 가지 법칙. 프런트 엔드는 클라이언트 시간대에 따라 시간 값을 변환하는 방법을 스스로 결정해야합니다.

    나는이 기사의 저자와 동의한다. 우리가 저장하고 UTC로 시간을 반환해야하는 API 날짜와 시간의 5 가지 법칙. 프런트 엔드는 클라이언트 시간대에 따라 시간 값을 변환하는 방법을 스스로 결정해야합니다.

    이를 달성하기 위해 우리는 JVM 매개 변수 -Duser.timezone = UTC를 설정하거나 spring.jpa.properties.hibernate.jdbc.time_zone = UTC를 application.properties (Hibernate 5.2.3.Final에서 시작)에 추가합니다. . 그런 다음 엔티티의 시간 필드를 LocalDateTime (표준 시간대 정보를 저장하지 않음)에서 ZonedDateTime 유형으로 변경하십시오.

    그런 다음 시간 값은 응용 프로그램이 시작되는 컴퓨터의 현지 표준 시간대와는 별도로 UTC로 저장되며 SDR은 ISO8601 형식으로이 값을 반환합니다. 2017-07-02T11 : 58 : 10.089Z

    그러나 특정 시간대에서 시간 값을 반환해야하는 경우 @JsonFormat 주석을 모든 시간 필드에 설정해야합니다.

    @JsonFormat(timezone = "Europe/Rome", pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
    private ZonedDateTime createdDate;
    

    우리는 애플리케이션에서 상수 TIME_ZONE을 정의하고 @JsonFormat 주석 : @JsonFormat (timezone = Application.TIME_ZONE, ...)에서 설정할 수 있습니다.

    그런 다음이 결과를 얻습니다.

    {
        //...
        "createdDate": "2017-07-02T14:11:45.964+0200",
        //...
    }
    

    불행히도 매개 변수 spring.jackson.time-zone (짧은 조사 결과에 기반 함)은 응용 프로그램의 서비스 메시지에만 영향을줍니다. 예를 들면 다음과 같습니다.

    {
        "timestamp": "2017-07-02T14:14:09.486+0200",
        "status": 404,
        "error": "Not Found",
        "message": "No message available",
        "path": "/users"
    }
    

    여기서 '존 (zoned)'형태로 시간을 얻으려면 application.properties에 spring.jackson.date-format 매개 변수를 올바르게 설정해야합니다.

    spring.jackson.date-format=com.fasterxml.jackson.databind.util.StdDateFormat
    
  2. from https://stackoverflow.com/questions/44830861/spring-rest-localdate-utc-differs-of-one-day by cc-by-sa and MIT license