我将Spring Boot与以下对象映射器一起使用:
@Bean
public ObjectMapper objectMapper()
{
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true)); // Makes no difference to output
mapper.findAndRegisterModules();
return mapper;
}
当OffsetDateTimes被序列化并作为响应返回时,它们的格式如下:
"2020-02-28T12:28:29.01Z"
"2020-02-28T12:36:21.885Z"
我原以为最后的时区信息应该是这样的:
"2020-02-28T10:41:25.287+00:00"
我在这里缺少或做错了什么,或者无论如何我可以将时区信息序列化为 00 :00
格式而不是 885Z
格式?
非常感谢!
有几种可能性可以使用预构建的格式或为DateTimeFor的
提供自定义模式。
看看这些(非常简单的)例子:
public static void main(String[] arguments) {
Instant now = Instant.now();
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(now, ZoneId.of("UTC"));
OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(now, ZoneId.of("UTC"));
System.out.println(zonedDateTime.toString());
System.out.println(offsetDateTime.toString());
System.out.println(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
System.out.println(offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
System.out.println(zonedDateTime.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"))
);
System.out.println(offsetDateTime.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx")
)
);
}
我想你期待的是最后一个,一个以xxx
结尾的模式,这会导致偏移总是以HH: mm
的形式显示,代码示例的输出是:
2020-02-28T12:49:02.388Z[UTC]
2020-02-28T12:49:02.388Z
2020-02-28T12:49:02.388Z[UTC]
2020-02-28T12:49:02.388Z
2020-02-28T12:49:02+0000
2020-02-28T12:49:02+00:00
新的Java8 Time API提供了一个DateTimeForith
,您可以在其中将格式的末尾设置为一个或多个x
或X
。根据api描述:
偏移X和X:这根据模式字母的数量格式化偏移。一个字母只输出小时,如“01”,除非分钟是非零的,在这种情况下,分钟也输出,如“0130”。两个字母输出小时和分钟,不带冒号,如“0130”。三个字母输出小时和分钟,带冒号,如“01:30”。四个字母输出小时、分钟和可选的秒,不带冒号,如“013015”。五个字母输出小时、分钟和可选的秒,并带有冒号,如“01:30:15”。六个或更多的字母抛出IllegalArgumentException。当要输出的偏移量为零时,模式字母“X”(大写)将输出“Z”,而模式字母“X”(小写)将输出“00”、“0000”或“00:00”。
因此,在您的情况下,对于1:30
,您的格式化字符串应该以xxx
结尾,例如"yyyy-MM-dd'T'HH: mm:ss.SSSxxx"
,SSS
总是给出毫秒数。
要将这个< code>DateTimeFormatter用于Jackson,您需要定义一个自定义序列化程序
public class DefaultZonedDateTimeSerializer extends JsonSerializer<ZonedDateTime> {
private static final DateTimeFormatter ISO_8601_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
.withZone(ZoneId.of("UTC"));
@Override
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value == null) {
throw new IOException("ZonedDateTime argument is null.");
}
gen.writeString(ISO_8601_FORMATTER.format(value));
}
并用
@JsonSerialize(using = DefaultZonedDateTimeSerializer.class)
private ZonedDateTime someTimeProperty;
或者您需要从 DateTimeFormatter
转换为 DateFormat
(较旧,但由 Jackson 使用),如下所述:将 DateTimeFormatter 与 ObjectMapper 一起使用
以下步骤解决了此问题(取自https://stackoverflow.com/a/41893238/12177456),还感谢@Ralf Wagner和@deHaar:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.6.5</version>
</dependency>
public class OffsetDateTimeSerializer extends JsonSerializer<OffsetDateTime>
{
private static final DateTimeFormatter ISO_8601_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx")
.withZone(ZoneId.of("UTC"));
@Override
public void serialize(OffsetDateTime value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
{
if (value == null) {
throw new IOException("OffsetDateTime argument is null.");
}
jsonGenerator.writeString(ISO_8601_FORMATTER.format(value));
}
}
@Bean
public ObjectMapper objectMapper()
{
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
objectMapper.registerModule(new JavaTimeModule());
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer());
objectMapper.registerModule(simpleModule);
return objectMapper;
}
问题内容: 我最近接手了一个十年前创建的旧项目。它使用MySQL 5.1。 除其他外,我需要将默认字符集从latin1更改为utf8。 例如,我有这样的表: 我设置了自己的Mac来进行此工作。不用考虑太多,我运行了“ brew install mysql”,它安装了MySQL 5.7。所以我有一些版本冲突。 我下载了此数据库的副本并将其导入。 如果我尝试运行这样的查询: 我收到此错误: 我以为可以
问题内容: 我有一个包含日期的数据库表 我正在使用MySQL。有时从程序中将没有日期的数据传递到数据库。因此, 当使用带错误的日期列调用表数据时,日期值会自动分配给它 在插入数据时,我尝试将null值传递给日期,但是将其分配给当前时间。 有什么办法可以在不更改表结构的情况下获得? 问题答案: 您可以在数据源配置中直接使用此JDBC URL: jdbc:mysql://您的服务器:3306 /您的数
问题内容: 我在用Java重置小时数时遇到问题。对于给定的日期,我要将小时设置为00:00:00。 这是我的代码: 问题是,有时时间是,有时是时间,当我查询数据库中保存的实体以及查询的实际实体时间(存储的实际时间)失败时。 我知道! 我正在使用AppEngine。这是Appengine错误,问题还是其他问题?还是取决于其他因素? 问题答案: 使用另一个常数代替,使用。 使用0-11(与AM / P
问题内容: 字段定义 二传手 有谁知道如何将“零日期”转换为适当的值?因为我有错误: 即使我像这样设置“默认”字段和设置器: 我仍然会有同样的问题。 问题答案: 在这里,我将大胆猜测您正在使用MySQL :-)它使用“零日期”作为特殊占位符 -不幸的是,JDBC默认情况下无法处理它们。 解决方案是将“ zeroDateTimeBehavior = convertToNull”指定为MySQL连接的
问题内容: 字段定义 二传手 有谁知道如何将“零日期”转换为适当的值?因为我有错误: 即使我像这样设置“默认”字段和设置器: 我仍然会有同样的问题。 问题答案: 在这里,我将做出一个疯狂的猜测,即您正在使用MySQL :-)它使用“零日期”作为特殊的占位符 -不幸的是,默认情况下JDBC无法处理它们。 解决方案是将“ zeroDateTimeBehavior = convertToNull”指定为
我想在MySQL中允许零日期。我已将更改为。 我已经在中更改了它。 然而,当我尝试插入数据时,我得到了错误, 数据截断:不正确的datetime值:“0000-00-00 00:00:00” MySQL版本为5.7.18。 这方面的任何想法都将大有帮助。