发布日期被序列化为错误的日期,休息 1 天

Posted date is serialized to wrong date with 1 day off

我 post 使用数据 departureTime: "2019-10-21" 到我的端点,我在我的 spring 程序中输出接收到的 departmentTime 变量。

@CrossOrigin(origins = "*")
@RequestMapping(value="/travel/query", method= RequestMethod.POST)
public ArrayList<TripResponse> query(@RequestBody QueryInfo info,@RequestHeader HttpHeaders headers){

    if(info.getStartingPlace() == null || info.getStartingPlace().length() == 0 ||
            info.getEndPlace() == null || info.getEndPlace().length() == 0 ||
            info.getDepartureTime() == null){
        System.out.println("[Travel Service][Travel Query] Fail.Something null.");
        ArrayList<TripResponse> errorList = new ArrayList<>();
        return errorList;
    }
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    Calendar ca = Calendar.getInstance();
    ca.setTime(info.getDepartureTime());
    System.out.println("Departure date is " + format.format(ca.getTime()));

    ...
}


public class QueryInfo {

    @Valid
    @NotNull
    private String startingPlace;

    @Valid
    @NotNull
    private String endPlace;

    @Valid
    @NotNull
    private Date departureTime;

    public QueryInfo(){
        //Default Constructor
    }

    public String getStartingPlace() {
        return startingPlace;
    }

    public void setStartingPlace(String startingPlace) {
        this.startingPlace = startingPlace;
    }

    public String getEndPlace() {
        return endPlace;
    }

    public void setEndPlace(String endPlace) {
        this.endPlace = endPlace;
    }

    public Date getDepartureTime() {
        return departureTime;
    }

    public void setDepartureTime(Date departureTime) {
        this.departureTime = departureTime;
    }
}

控制台显示"Departure date is 2019-10-20".

我的 spring 程序 运行 服务器应该使用 UTC-7 时区。

知道为什么会发生这个错误吗?我该如何做最小的改变来修复它?

编辑:

我运行

 System.out.println(ca.getTimeZone().toString());

它输出sun.util.calendar.ZoneInfo[id="America/Los_Angeles"...。我认为是正确的。

Calendar.getInstance() 将根据托管服务器的位置设置时区。因此,如果您不在 UTC-7 时区,您会看到时间上的差异。

解决此问题的最佳方法通常是使用特定时区,例如 UTC,或用于数据的任何其他时区。然后您可以获得该特定时区的 Calendar,如下所示:

Calendar.getInstance(TimeZone.getTimeZone("UTC"))

避免使用 SimpleDateFormat & Calendar,而是使用 ZonedDateTime.

示例:

ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))

示例输出:

2019-10-22

或者,如果您想继续使用 java.util 包中的旧 API,那么您必须使用这个:

ca.setTimeZone(TimeZone.getTimeZone("UTC")); // to set the time zone for using calendar API.
format.setTimeZone(TimeZone.getTimeZone("UTC")); // set timezone for formatter.

另一种解决方案(虽然不是聪明的,但有效)可以是,您将 DTOs 中的 dateField 定义为字符串字段。因此,您发送的内容将得到相同的结果,没有基于时区或其他内容的日期转换。然后您可以将该字符串转换为您喜欢的日期 format/timezone.