gpt4 book ai didi

java - Spring Json 响应中的时区问题

转载 作者:行者123 更新时间:2023-12-01 19:41:05 26 4
gpt4 key购买 nike

我在 JSON 输出中显示日期时遇到问题。在代码中我使用 java.util.Date ,其值为 2019-03-07 但在 JSON 中我得到 2019-03-06 23:00:00 。我认为问题出在时区,但我也不在数据库和代码中使用时区。

我试图用它来修复它

@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone="UTC")

@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone="欧洲/华沙")

第一个没有帮助,第二个有帮助,但我不接受这个解决方案。

我的 Controller 的一部分:

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 始终以本地时区显示日期?

最佳答案

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 并强制重新计算值,将毫秒设置为 0:

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

这就是为什么 Date 已经过时并且应该使用 java.time 包的原因。如果您不想显示时间,只需将日期格式更改为 @JsonFormat(pattern = "yyyy-MM-dd")

另请参阅:

关于java - Spring Json 响应中的时区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55380919/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com