java—是否可以使jsonformat datetime的某些部分成为可选的?

vnjpjtjt  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(417)

我有一个用秒部分定义的字段,(即:“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-02-13t16:02 est”将解析为“thu feb 13 16:02 est 2020”
我在想这样的事情(虽然这不起作用……):“yyy-mm-dd't'hh:mm[:ss]z”
谢谢。

zf2sa74q

zf2sa74q1#

我知道答案了。
添加自定义反序列化程序类“datedeserializer.class”
datedeserializer.class实现了包含和不包含第二部分的模式。
代码示例如下:

@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);
        }
    }
}
}
46qrfjad

46qrfjad2#

自从 SimpleDateFormat 类是出了名的麻烦和过时的,而且也不是线程安全的,我想我应该向您展示如何使用java.time(现代的java日期和时间api)来解决您的任务。现在我假设你不能改变你的类型 date field,它需要 Date ,并且不能更改格式。我把你自己的答案改写成这样:

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);
    }
}

在格式模式字符串中,我使用方括号, [] ,大约在一分钟的可选秒数。 DateTimeFormatter 是线程安全的(相反 SimpleDateFormat ),因此即使从多个线程使用,也可以只使用一个静态示例。 DateTimeFormatter.parse() 如果无法解析字符串,则抛出一个运行时异常(unchecked exception),因此我没有找到任何理由在我们自己的代码中显式显示该异常。
如果您可以进行以下任何更改,则仍会改善问题:
例如,教育日期时间字符串的源使用iso8601格式 2020-02-13T16:02:11-05:00 . 他们现在使用的格式是iso8601和非iso的特殊混合,因此您和他们实际上既没有获得标准的优势,也没有获得更具可读性的格式的全部潜在优势。iso8601的格式化程序内置在java.time中,因此使用该标准可以避免我们自己定义任何格式化程序。在ISO8601中,秒是可选的,因此它们仍然可以发送带秒和不带秒的字符串。
扔掉那些垃圾 Date 班级。它设计拙劣,过时已久。使用 Instant 或者java.time中的另一个类,并保存我在代码中所做的转换。

链接

oracle教程:date time解释如何使用java.time。
维基百科文章:iso 8601

相关问题