【问题标题】:Java.util auto correcting invalid dateJava.util 自动更正无效日期
【发布时间】:2018-12-22 11:01:38
【问题描述】:

Java.util.date 包是自动更正日期。例如:如果我们将日期传递为“2018-02-35”,它会自动将其更改为“2018-03-07”,这是一个有效的日期。

基本上,要求是验证用户输入的日期,但随着日期自动更正,模块永远无法找到不正确的日期。 (注意:由于一些特殊限制,无法进行UI验证,因此必须由中间件系统进行验证。

有没有办法我可以使用相同的 util 包来处理这个问题,或者可以通过任何 3rd 方 jar 来处理这个问题?请指教

【问题讨论】:

  • 休息服务无法接收 XMLGregorianCalendar 对象。您的意思是您正在接收正在解析为 XMLGregorianCalendar 对象的文本?如果是这样,你得到了什么文本?只是这里显示的月份和日期?你的问题写得不好,不清楚。为了清楚起见,我建议您重写。正如目前所写的那样,我必须投票结束,因为不清楚。
  • 这是一个从 xsd 生成的 jaxb 对象,该字段在 xsd 模式中定义为日期,因此 jaxb 类创建了一个 xmlgregoriancalendar 对象。值作为“yyyy-MM-yyThh:mm:ss.sss”传递。当我尝试通过调用适当的“getter”bean 来读取输入时,值会自动更改,这就是问题所在。希望这次我说清楚了
  • 将更多详细信息发布为对您的问题的编辑,而不是 cmets。
  • 欢迎来到 Stack Overflow。我承认,即使在您编辑之后,从您的问题来看,我对正在发生的事情也不是很清楚。我认为如果您create a Minimal, Complete, and Verifiable example,我们将能够为您提供帮助。我们很乐意这样做。
  • 您是否知道java.util.Date 类的设计过时和糟糕?对于没有时间的日期,您应该更喜欢使用 java.time.LocalDate

标签: date auto java.util.date xmlgregoriancalendar


【解决方案1】:

即使我也面临同样的问题。但经过一番研究,我发现 DateFormat 类中有一个方法 (setLenient()) 可以禁用此行为。

DateFormat df = new SimpleDateFormat(DATE_FORMAT);
df.setLenient(false);

Java 文档: 指定日期/时间解析是否宽松。通过宽松的解析,解析器可以使用启发式方法来解释不精确匹配该对象格式的输入。使用严格解析,输入必须匹配此对象的格式。

【讨论】:

  • 感谢 Neeraj,但此值是从休息服务调用(Json 值)中读取的,因此在映射到输入 VO 之前会自动更正输入,因此它不会让我应用任何格式
  • 即使我也在读取来自 rest 调用的值(json 值)。为此,您可以编写 DateDeserializer 并使用该 DateDeserializer 在媒体类中注释您的日期属性。在另一条评论中查看代码sn-p
  • 我通过将 lenient 属性设置为 false 来使用 @jsonformat 注释(必须是 2.9 及更高版本)解决了这个问题
  • 请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API 和它的DateTimeFormatter 中做得更好。
【解决方案2】:

你可以写 DateDeserializer

public class DateDeserializer extends JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", getLocale());
        format.setLenient(false); // if true, will auto correct the date  
                                  // to the next possible valid date
        String date = jp.getText();
        try {
            return format.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    private Locale getLocale() {
        Locale locale = (LocaleContextHolder.getLocale() != null) ? LocaleContextHolder.getLocale() : Locale.getDefault();
        return locale;
    }

}

然后使用此 DateDeserializer 在媒体类中注释您的日期属性。您还可以使用 dateSerializer 将对象序列化回 Json 格式。下面的例子

@JsonSerialize(using=DateSerializer.class)
@JsonDeserialize(using=DateDeserializer.class)
private Date startDate;

【讨论】:

  • 您可以编辑旧答案,而不是提供新答案。你下面有an edit link
猜你喜欢
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 2023-01-30
  • 2013-03-29
  • 2019-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多