gson 如何设置Date对象的格式以匹配@JsonFormat?

u59ebvdq  于 2022-11-06  发布在  其他
关注(0)|答案(4)|浏览(134)

我有一个json格式的响应日期到控制器,这是这样的:

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "America/Chicago")
private Date date;

因此,当我进行post调用时,它看起来像:

"date": "2021-08-20 14:17:43"

因此响应字符串看起来像{"date":"2021-05-21 14:23:44"}。在JUnit中,我手动创建了一个响应对象并设置了Date对象,这样我就可以使用Gson将其转换为字符串,然后Assert两者相等。我尝试在我的SpringMVC JUnit测试用例中匹配这一点,方法是:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("America/Chicago"));

String formattedDate = sdf.format(new Date());
LocalDate localDate = LocalDate.parse(formattedDate);

Date date = Date.from(localDate.atStartOfDay(ZoneId.of("America/Chicago")).toInstant());

但是,由于yyyy-MM-ddHH:mm:ss之间的空格,解析时出错:

java.time.format.DateTimeParseException: Text '2021-08-20 14:23:44' could not be parsed, unparsed text found at index 10

我想这样做可能效率不高,所以我想知道是否有更简单的方法来创建与@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "America/Chicago")匹配的Date对象
我正在尝试匹配响应体,以便它通过mockito传递。

2guxujil

2guxujil1#

不要混合使用现代和传统的日期-时间API

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDate = "2021-08-20 14:17:43";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse(strDate, dtf);
        System.out.println(ldt);

        // Get the required Instant
        ZonedDateTime zdtUtc = ldt.atZone(ZoneOffset.UTC);
        ZonedDateTime zdtChicago = zdtUtc.withZoneSameInstant(ZoneId.of("America/Chicago"));
        Instant instant = zdtChicago.toInstant();
        System.out.println(instant);
    }
}

输出:

2021-08-20T14:17:43
2021-08-20T14:17:43Z

ONLINE DEMO

*java.时间 *

java.util日期-时间API及其格式化API SimpleDateFormat已过时且容易出错。建议完全停止使用它们并切换到modern Date-Time API *。但是,无论出于何种原因,如果您需要将Instant对象转换为java.util.Date对象,您可以执行以下操作:

Date date = Date.from(instant);

从**Trail: Date Time**了解有关现代日期-时间API的更多信息。

41ik7eoe

41ik7eoe2#

您可能缺少日期反序列化程序

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
gev0vcfq

gev0vcfq3#

发布这篇文章只是为了满足你想要达到的目标。但是你应该按照@Arvind的回答去做:

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.TimeZone;

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
String formattedDate = sdf.format(new Date());

// Updated the lines below
LocalDateTime localDateTime = LocalDateTime.parse(formattedDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Date date = Date.from(localDateTime.atZone(ZoneId.of("America/Chicago")).toInstant());
ih99xse1

ih99xse14#

最好是完全跳过Date类,在响应中使用java.time(现代Java日期和时间API)中的InstantZonedDateTime

如果无法避免使用过期的Date类

......我想知道是否有更简单的方法来生成与@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "America/Chicago")相匹配的Date对象

**基本编辑:**这在很大程度上取决于您所说的 * 匹配格式 * 是什么意思。Date既不能有格式,也不能有时区。JSON中的字符串具有上面提到的格式。Date没有,因为这是不可能的。时区America/芝加哥在JSON和Date中都不存在。它只用于在两者之间进行转换。如果两个Date对象表示相同的时间点,则它们是相等的,没有其他任何问题。当您询问如何将Date化为匹配@JsonFormat时,这必然意味着将 * 格式化为字符串 *。

要将2021-08-20 14:23:44这样的字符串转换为老式的Date对象,我首先要静态定义格式和时区:

private static final DateTimeFormatter FORMATTER
        = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ROOT);
private static final ZoneId ZONE = ZoneId.of("America/Chicago");

然后做:

String responseDateString = "2021-08-20 14:23:44";

    Instant inst = LocalDateTime.parse(responseDateString, FORMATTER)
            .atZone(ZONE)
            .toInstant();
    Date oldfashionedDate = Date.from(inst);

    System.out.println(oldfashionedDate);

我的时区中的输出为:
欧洲中部时间2021年8月20日星期五21:23:44
如果我在跑步前将时区设置为“America/芝加哥,则更容易看出结果是否正确:
2021年8月20日星期五14:23:44 CDT

您的代码中出现了什么错误?

首先,将一个Date化为字符串,然后再解析它,这会使事情变得过于复杂,这是正确的;其次,注意到异常来自下面这一行:

LocalDate localDate = LocalDate.parse(formattedDate);

LocalDate是一个没有时间的日期。因此它的单参数parse方法只需要字符串中的2021-08-20,没有其他内容。它抱怨空格,不是因为它是一个空格,而是因为在预期的字符后面有更多的字符。

相关问题