Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以将JsonFormat datetime的某些部分设置为可选的?_Java_Json_Date_Datetime_Format - Fatal编程技术网

Java 是否可以将JsonFormat datetime的某些部分设置为可选的?

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

我有一个用秒部分定义的字段,(即:“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”
我在想这样的事情(尽管这不起作用……): “yyyy-MM-dd'HH:MM[:ss]z”

谢谢。

我得到了答案

  • 添加自定义反序列化程序类“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);
            }
        }
    }
    } 
    
    @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格式,例如
      2020-02-13T16:02:11-05:00
      。他们现在使用的格式是ISO 8601和非ISO的特殊组合,因此您和他们实际上既没有获得标准的优势,也没有获得更具可读性的格式的全部潜在优势。ISO 8601的格式化程序内置于java.time中,因此使用该标准可以避免我们自己定义任何格式化程序。在ISO8601中,秒是可选的,因此它们仍然可以发送带秒和不带秒的字符串
    • 扔掉
      日期
      类。它设计拙劣,早已过时。使用
      Instant
      或java.time中的其他类,并在代码中保存我正在进行的转换
    链接
    • 解释如何使用java.time

    您需要使用
    日期
    类吗?那门课设计得很糟糕,而且早已过时。我会从中尝试
    ZoneDateTime
    。你需要依赖一个三个字母的时区缩写吗<代码>EST模棱两可,因此我认为您无法确定您得到了什么。感谢您回答自己的问题。
    SimpleDataFormat
    类是出了名的麻烦和过时的。而且它不是线程安全的,所以如果您仍然想使用它,请不要将其存储到静态字段中。