복붙노트

[SPRING] Spring의 Json 응답 시간대 문제

SPRING

Spring의 Json 응답 시간대 문제

JSON 출력에 날짜를 표시하는 데 문제가 있습니다. 코드에서 java.util.Date를 사용하고 값은 2019-03-07이지만 JSON에서는 2019-03-06 23:00:00입니다. 문제는 시간대에 있다고 생각하지만 DB와 코드에서 시간대를 사용하지 않습니다.

나는 그것을 고치려고 노력했다.

@JsonFormat (패턴 = "yyyy-MM-dd hh : mm : ss", 시간대 = "UTC")

@JsonFormat (패턴 = "yyyy-MM-dd hh : mm : ss", 시간대 = "유럽 / 바르샤바")

첫 번째는 도움이되지 않았지만 두 번째는 도움이되었지만이 솔루션을 허용하지 않았습니다.

내 컨트롤러의 일부 :

return new ThisDay(
    sysoperMgr.getToday(),
    new Date()
);

이것은 내가 반환하는 대상입니다.

@Getter
@Setter
public class ThisDay {

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

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

    public BiezacaDoba(Date dataZamkniecia, Date dataSystemowa) {
        this.dataZamkniecia = dataZamkniecia;  // cdate = 2019-03-07T00:00:00.000+0100
        this.dataSystemowa = dataSystemowa; // cdate = 2019-03-27T16:08:12.343+0100
    }
}

이 함수는 날짜를 가져옵니다.

public Date getToday() {

    Timestamp timestamp = sysoperDao.getDataOstatniejZamknietejDoby(); // cdate = 2019-03-06T00:00:00.000+0100
    java.util.Date lastDay = new java.sql.Date(misc.roundTimestamp(timestamp).getTime()); // cdate = 2019-03-06T00:00:00.000+0100
    java.util.Date thisDay = misc.incrementDate(ostatniaDoba, Increment.DAILY, 1); // cdate = 2019-03-07T00:00:00.000+0100
    return thisDay;
}

Json 결과 :

{
  "dataZamkniecia":"2019-03-06 23:00:00",
  "dataSystemowa": "2019-03-27 15:12:15"
}

JSON을 사용하여 날짜를 항상 현지 시간대로 표시하려면 어떻게해야합니까?

해결법

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

    1.날짜는 오래된 클래스이므로 Java 8이 java.time 패키지를 릴리스했거나 Joda-Time을 사용할 수 있으므로 사용해서는 안됩니다. Timestamp에서 java.sql.Date로 날짜를 변환하고 나중에 java.util.Date로 변환합니다. 아래 예제를 보면 매우 안전하지 않습니다.

    날짜는 오래된 클래스이므로 Java 8이 java.time 패키지를 릴리스했거나 Joda-Time을 사용할 수 있으므로 사용해서는 안됩니다. Timestamp에서 java.sql.Date로 날짜를 변환하고 나중에 java.util.Date로 변환합니다. 아래 예제를 보면 매우 안전하지 않습니다.

    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    
    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.TimeZone;
    
    public class JsonApp {
    
        public static void main(String[] args) throws Exception {
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
    
            // Java time precise dates
            LocalDate localDateOpened = LocalDate.of(2019, 03, 07);
            LocalDate localDateClosed = localDateOpened.plusDays(20);
    
            ZoneId utc = ZoneId.of("UTC");
            Date opened = Date.from(localDateOpened.atStartOfDay(utc).toInstant());
            Date closed = Date.from(localDateClosed.atStartOfDay(utc).toInstant());
    
            System.out.println("Dates generated from java.time.*");
            System.out.println(mapper.writeValueAsString(new ThisDay(opened, closed)));
    
            // Calculate dates with default timezone
            Calendar calendar = Calendar.getInstance();
            opened = calendar.getTime();
            calendar.add(Calendar.DAY_OF_MONTH, 20);
            closed = calendar.getTime();
    
            System.out.println("Dates generated from Calendar");
            System.out.println(mapper.writeValueAsString(new ThisDay(opened, closed)));
    
            // Calculate dates with UTC timezone
            calendar = Calendar.getInstance();
            calendar.setTimeZone(TimeZone.getTimeZone(utc));
            calendar.set(Calendar.MILLISECOND, 0); // Recompute
    
            opened = calendar.getTime();
            calendar.add(Calendar.DAY_OF_MONTH, 20);
            closed = calendar.getTime();
    
            System.out.println("Dates generated from UTC Calendar");
            System.out.println(mapper.writeValueAsString(new ThisDay(opened, closed)));
        }
    }
    
    class ThisDay {
    
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date opened;
    
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date closed;
    
        public ThisDay(Date opened, Date closed) {
            this.opened = opened;
            this.closed = closed;
        }
    
        public Date getOpened() {
            return opened;
        }
    
        public void setOpened(Date opened) {
            this.opened = opened;
        }
    
        public Date getClosed() {
            return closed;
        }
    
        public void setClosed(Date closed) {
            this.closed = closed;
        }
    }
    

    위 코드 인쇄 :

    Dates generated from java.time.*
    {
      "opened" : "2019-03-07 00:00:00",
      "closed" : "2019-03-27 00:00:00"
    }
    Dates generated from Calendar
    {
      "opened" : "2019-03-27 23:45:12",
      "closed" : "2019-04-16 22:45:12"
    }
    Dates generated from UTC Calendar
    {
      "opened" : "2019-03-28 00:45:12",
      "closed" : "2019-04-17 00:45:12"
    }
    

    두 번째 및 세 번째 날짜의 차이는 한 시간입니다. 수동으로 달력 표준 시간대를 UTC로 설정하고 milliseconds를 0으로 설정하는 값을 다시 계산하도록합니다.

    calendar.setTimeZone(TimeZone.getTimeZone(utc));
    calendar.set(Calendar.MILLISECOND, 0); // Recompute
    

    이것이 Date가 구식이며 java.time 패키지가 사용되어야하는 이유입니다. 시간을 표시하고 싶지 않으면 날짜 만 @JsonFormat (pattern = "yyyy-MM-dd") 형식으로 변경하십시오.

    참조 :

  2. from https://stackoverflow.com/questions/55380919/problem-with-timezone-in-json-response-from-spring by cc-by-sa and MIT license