问题描述
我有一个 OffsetDateTime。 在 json 中使用 Jackson 我看到了这个值:
2021-03-01T22:21:02.8624372-05:00
在我使用的领域
@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ssZ")
显示此值
2021-03-01T22:21:02-0500
任何想法
2021-03-01T22:21:02-05:00
解决方法
我在使用 onCreateView
时遇到了类似的问题。在那里,我覆盖了 .observe(getViewLifecycleOwner()
的 to get the Lifecycle specifically associated with the Fragment's view,which is the correct scope for any Observer that updates your Fragment's UI (such as your
序列化程序,并使用了这样的自定义 Instant
:
Instant
但您也应该能够在该特定字段上使用 JavaTimeModule
而不是 DateTimeFormatter
:
ObjectMapper objectMapper = new ObjectMapper();
DateTimeFormatter instantFormatter = new DateTimeFormatterBuilder()
.appendInstant(0)
.toFormatter();
JavaTimeModule jtm = new JavaTimeModule();
jtm.addSerializer(Instant.class,new JsonSerializer<Instant>() {
@Override
public void serialize(Instant value,JsonGenerator gen,SerializerProvider serializers) throws IOException,JsonProcessingException {
gen.writeString(instantFormatter.format(value));
}
});
objectMapper.registerModule(jtm);
DateTimeFormatterBuilder
让您轻松自定义格式
假设您已经在使用 JavaTimeModule
(将 WRITE_DATES_AS_TIMESTAMPS
作为 false
,在您的第一个代码段中产生输出),您只需在 @JsonFormat
中提供适当的日期模式{1}},即。
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZZZZZ")
pattern
在哪里
特定于数据类型的附加配置,可用于进一步优化格式化方面。例如,这可以确定用于 java.util.Date
序列化的低级格式字符串;但是,确切的使用取决于特定的 JsonSerializer
此处的“特定于日期类型”是 JsonSerializer
的序列化程序。由于您使用的是 JavaTimeModule
(假设!!!),那就是 OffsetDateTimeSerializer
。 @JsonFormat
pattern
被解释为一个 DateTimeFormatter
模式,该模式声明
Offset Z:根据模式字母的数量格式化偏移量。一、二或三个字母输出小时和分钟,不带冒号,例如“+0130”。当偏移量为零时,输出将为“+0000”。四个字母输出局部偏移的完整形式,相当于Offset-O的四个字母。如果偏移为零,则输出将是相应的本地化偏移文本。 五个字母输出小时、分钟,如果非零,可选秒,带冒号。如果偏移为零,则输出“Z”。六个或更多字母抛出 IllegalArgumentException
。
嗯,有很多方法可以做到,下面的代码显示了简单的两种方法:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class JsonDateFormat {
/*
* Approach I
*/
@SuppressWarnings("static-method")
public String getCurrentDateTime() {
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.now());
}
/*
* Approach II
*/
@SuppressWarnings("static-method")
@JsonSerialize(using = CustomDateTimeFormatter.class)
public Date getCustomCurrentDateTime() {
return new Date();
}
public static void main(final String[] args) throws JsonProcessingException {
final JsonDateFormat jsonDateFormat = new JsonDateFormat();
final String result = new ObjectMapper().writeValueAsString(jsonDateFormat);
System.out.println(result);
}
}
下面是自定义字段序列化器。
import java.io.IOException;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class CustomDateTimeFormatter extends StdSerializer<Date> {
private static final long serialVersionUID = 1L;
public CustomDateTimeFormatter() {
this(null);
}
public CustomDateTimeFormatter(final Class<Date> t) {
super(t);
}
@Override
public void serialize(final Date date,final JsonGenerator jgen,final SerializerProvider provider) throws IOException {
final String dateTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault()));
jgen.writeObject(dateTime);
}
}
最后,您还可以使用自定义 DateTimeFormatter。见参考DateTimeFormatter doesn't parse custom date format