如何格式化日期对象匹配@JsonFormat?



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

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

所以当我进行post call时,它看起来像:

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

所以响应字符串看起来像这样{"date":"2021-05-21 14:23:44"}。在JUnit中,我手动创建一个响应对象并设置Date对象,这样我就可以使用Gson将其转换为字符串,然后断言两者是相等的。我试图在我的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

我想我可能这样做效率低下,所以我想知道是否有一个更简单的方法来制作一个Date对象,将匹配@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "America/Chicago")的格式

我正在尝试匹配响应体,以便它通过mockito传递。

不要混合使用现代和旧的日期时间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
<<p>在线演示/kbd>

java.time

java.util日期-时间API和它们的格式化API,SimpleDateFormat是过时的和容易出错的。建议完全停止使用它们并切换到现代的Date-Time API*。然而,无论出于何种原因,如果您需要将Instant的对象转换为java.util.Date的对象,您可以这样做:

Date date = Date.from(instant);

Trail: Date Time了解更多关于现代Date-Time API的信息.


*无论什么原因,如果你必须坚持Java 6或Java 7,你可以使用ThreeTen-Backport支持大部分java。time功能到Java 6 &7. 如果你正在为一个Android项目工作,而你的Android API级别仍然不符合Java-8,请检查Java 8+ API,通过desugaring和如何在Android项目中使用ThreeTenABP。

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

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

发布这篇文章只是为了满足你想要实现的目标。但是你应该关注@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());

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

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

…我想知道是否有一种更简单的方法来制作Date对象匹配@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "America/Chicago")

的格式

基本编辑:这在很大程度上取决于您对的定义是否匹配格式Date既不能有格式也不能有时区。JSON中的字符串具有上述格式。Date没有,因为这是不可能的。时区America/Chicago在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);

我所在时区的输出是:

星期五Aug 20 21:23:44 CEST 2021

如果我在运行之前将时区设置为美国/芝加哥,则更容易看到结果是正确的:

8月20日星期五14:23:44 CDT 2021

你的代码出了什么问题?

首先,您是正确的,将Date格式化为字符串只是为了解析它是过于复杂的事情。其次,您注意到异常来自这一行:

LocalDate localDate = LocalDate.parse(formattedDate);

LocalDate是没有时间的日期。所以它的一个参数parse方法只期望字符串中的2021-08-20,仅此而已。它在抱怨空格,不是因为它是一个空格,而是因为在预期的字符之后有更多的字符。

相关内容

  • 没有找到相关文章