多个模式的绑定日期

fuj*_*ujy 8 spring date spring-mvc date-format jodatime

我曾经使用像这样的Spring 属性来支持Java DateJoda Localdate模式绑定DateTimeFormat pattern

@DateTimeFormat(pattern = "dd.MM.yyyy")
private LocalDate creationDate;
Run Code Online (Sandbox Code Playgroud)

但我需要支持两种日期模式,例如:

如果用户输入31/12/199931/12/99,则两者都可以绑定到相同的值31/12/1999.是否可以为此定义两种模式@DateTimeFormat

编辑:

我试图将模式更改为

@DateTimeFormat(pattern = "dd.MM.yy")
private LocalDate creationDate;
Run Code Online (Sandbox Code Playgroud)

我发现它可以处理这两种情况(例如当用户输入31/12/1999或者31/12/99两者都受到约束时)31/12/1999.任何意见?

Men*_*ild 4

在我看来,绑定到 type 属性的 spring 注释 @DateTimeFormatLocalDate将导致 Spring 选择 JodaTime-Formatter,而不是标准格式化程序,否则 Spring 将无法成功将任何输入字符串解析为 type 对象LocalDate这个说法是在Spring源码的分析上完成的(参见方法的实现getParser(DateTimeFormat annotation, Class<?> fieldType))。

如果是这样,那么问题仍然是为什么您的解决方法和解决方案“dd.MM.yy”能够解析两位数年份以及正常的四位数年份。答案可以在 Joda 源代码和文档中找到。

org.joda.time.format.DateTimeFormat源代码摘录(在私有方法中完成 JodaTime 的模式分析parsePatternTo(DateTimeFormatterBuilder builder, String pattern)):

    case 'y': // year (number)
    case 'Y': // year of era (number)
        if (tokenLen == 2) {                    
          boolean lenientParse = true;
          // Peek ahead to next token.
          if (i + 1 < length) {
            indexRef[0]++;
            if (isNumericToken(parseToken(pattern, indexRef))) {
              // If next token is a number, cannot support
              // lenient parse, because it will consume digits that it should not.                            
              lenientParse = false;                        
            }
            indexRef[0]--;
          }
          // Use pivots which are compatible with SimpleDateFormat.                                       
          switch (c) {
            case 'x':
              builder.appendTwoDigitWeekyear(new DateTime().getWeekyear() - 30, lenientParse);
              break;
            case 'y':
            case 'Y':
            default:
                builder.appendTwoDigitYear(new DateTime().getYear() - 30, lenientParse);
                break;                    
          }
Run Code Online (Sandbox Code Playgroud)

因此我们认识到 JodaTime 将模式表达式“yy”转换为对 builder-method 的调用,appendTwoDigitYear()并将参数 lenientParse 设置为true。同样有趣的是,所选的枢轴年偏离了通常的 Joda 设置(+/-50 年),即(-80/+20 年)。

提到的构建器方法的 Javadoc中说:

“lenientParse - 当为 true 时,如果数字计数不为 2,则将其视为绝对年份”

这充分解释了为什么“dd.mm.yy”可以像解析四位数年份一样解析两位数年份。