Java 是否可以将JsonFormat datetime的某些部分设置为可选的?
我有一个用秒部分定义的字段,(即:“ss”),如下所示Java 是否可以将JsonFormat datetime的某些部分设置为可选的?,java,json,date,datetime,format,Java,Json,Date,Datetime,Format,我有一个用秒部分定义的字段,(即:“ss”),如下所示 @JsonProperty("date") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss z") private Date date; 是否可以选择秒部分?这样,以下两个日期字符串都可以工作: “2020-02-13T16:02:11 EST”将被解析为“Thu Feb 13 16:02:11 EST 2020” “2020-0
@JsonProperty("date")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss z")
private Date date;
是否可以选择秒部分?这样,以下两个日期字符串都可以工作:
- “2020-02-13T16:02:11 EST”将被解析为“Thu Feb 13 16:02:11 EST 2020”
- “2020-02-13T16:02 EST”将解析为“Thu Feb 13 16:02 EST 2020”
@JsonDeserialize(using = DateDeserializer.class)
@JsonProperty("date")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss z")
public class DateDeserializer extends StdDeserializer<Date> {
private static final SimpleDateFormat withSeconds = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss z");
private static final SimpleDateFormat withoutSeconds = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm z");
public DateDeserializer() {
this(null);
}
public DateDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String dateString = p.getText();
if (dateString.isEmpty()) {
//handle empty strings however you want,
//but I am setting the Date objects null
return null;
}
try {
return withSeconds.parse(dateString);
} catch (ParseException e) {
try {
return withoutSeconds.parse(dateString);
} catch (ParseException e1) {
throw new RuntimeException("Unable to parse date", e1);
}
}
}
}
@JsonDeserialize(使用=DateDeserializer.class)
@JsonProperty(“日期”)
@JsonFormat(shape=JsonFormat.shape.STRING,pattern=“yyyy-MM-dd'T'HH:MM:ss-z”)
公共类DateDeserializer扩展了StdDeserializer{
私有静态最终SimpleDataFormat with seconds=新SimpleDataFormat(“yyyy-MM-dd'T'HH:MM:ss z”);
私有静态最终SimpleDataFormat without秒=新SimpleDataFormat(“yyyy-MM-dd'T'HH:MM z”);
公共数据反序列化程序(){
这个(空);
}
公共日期反序列化程序(vc类){
超级(vc);
}
@凌驾
公共日期反序列化(JsonParser p,DeserializationContext ctxt)引发IOException,JsonProcessingException{
String dateString=p.getText();
if(dateString.isEmpty()){
//根据需要处理空字符串,
//但是我将日期对象设置为空
返回null;
}
试一试{
返回with seconds.parse(日期字符串);
}捕获(解析异常){
试一试{
返回withoutSeconds.parse(日期字符串);
}捕获(解析异常e1){
抛出新的RuntimeException(“无法分析日期”,e1);
}
}
}
}
由于SimpleDataFormat
类是出了名的麻烦、过时且线程不安全的类,我想我应该向您展示如何使用java.time(现代java日期和时间API)解决您的任务。现在我假设您不能更改日期
字段的类型,它必须是日期
,并且您不能更改格式。我以这种方式根据你自己的答案改写了课程:
public class DateDeserializer extends StdDeserializer<Date> {
private static final DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm[:ss] z", Locale.ENGLISH);
public DateDeserializer() {
this(null);
}
public DateDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String dateString = p.getText();
if (dateString.isEmpty()) {
//handle empty strings however you want,
//but I am setting the Date objects null
return null;
}
Instant parsedInstant = formatter.parse(dateString, Instant::from);
return Date.from(parsedInstant);
}
}
公共类DateDeserializer扩展StdDeserializer{
专用静态最终DateTimeFormatter格式化程序
=模式的日期时间格式(“uuu-MM-dd'T'HH:MM[:ss]z”,Locale.ENGLISH);
公共数据反序列化程序(){
这个(空);
}
公共日期反序列化程序(vc类){
超级(vc);
}
@凌驾
公共日期反序列化(JsonParser p,DeserializationContext ctxt)引发IOException,JsonProcessingException{
String dateString=p.getText();
if(dateString.isEmpty()){
//根据需要处理空字符串,
//但是我将日期对象设置为空
返回null;
}
Instant parsedInstant=formatter.parse(日期字符串,Instant::from);
返回日期。起始日期(parsedInstant);
}
}
在格式模式字符串中,我使用方括号,[]
,大约为可选的秒数DateTimeFormatter
是线程安全的(与之相反的是SimpleDataFormat
),因此即使从多个线程使用,也可以只使用一个静态实例DateTimeFormatter.parse()
如果无法解析字符串,则会引发运行时异常(未检查的异常),因此我没有找到任何理由在我们自己的代码中明确说明这一点
如果您可以进行以下任何一项更改,它仍将改善问题:
- 教育日期时间字符串的源使用ISO 8601格式,例如
。他们现在使用的格式是ISO 8601和非ISO的特殊组合,因此您和他们实际上既没有获得标准的优势,也没有获得更具可读性的格式的全部潜在优势。ISO 8601的格式化程序内置于java.time中,因此使用该标准可以避免我们自己定义任何格式化程序。在ISO8601中,秒是可选的,因此它们仍然可以发送带秒和不带秒的字符串2020-02-13T16:02:11-05:00
- 扔掉
类。它设计拙劣,早已过时。使用日期
或java.time中的其他类,并在代码中保存我正在进行的转换Instant
- 解释如何使用java.time
日期
类吗?那门课设计得很糟糕,而且早已过时。我会从中尝试ZoneDateTime
。你需要依赖一个三个字母的时区缩写吗<代码>EST模棱两可,因此我认为您无法确定您得到了什么。感谢您回答自己的问题。SimpleDataFormat
类是出了名的麻烦和过时的。而且它不是线程安全的,所以如果您仍然想使用它,请不要将其存储到静态字段中。