Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.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
Spring 多模式上的绑定日期_Spring_Date_Spring Mvc_Jodatime_Date Format - Fatal编程技术网

Spring 多模式上的绑定日期

Spring 多模式上的绑定日期,spring,date,spring-mvc,jodatime,date-format,Spring,Date,Spring Mvc,Jodatime,Date Format,我以前使用Spring属性在绑定中支持JavaDate或JodaLocalDate模式,如下所示 @DateTimeFormat(pattern = "dd.MM.yyyy") private LocalDate creationDate; 但我需要支持两种日期模式,例如: 如果用户输入了31/12/1999或31/12/99,则两者可以绑定到相同的值31/12/1999。是否可以为@DateTimeFormat定义两种模式 编辑: 我试着把模式改成 @DateTimeFormat(patte

我以前使用Spring属性在绑定中支持
JavaDate
JodaLocalDate
模式,如下所示

@DateTimeFormat(pattern = "dd.MM.yyyy")
private LocalDate creationDate;
但我需要支持两种日期模式,例如:

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

编辑:

我试着把模式改成

@DateTimeFormat(pattern = "dd.MM.yy")
private LocalDate creationDate;

我发现它可以处理这两种情况(例如,当用户输入
31/12/1999
31/12/99
)时,两者都绑定到
31/12/1999
。有什么意见吗?

for Spring的当前实现只允许设置一种模式

正如您的编辑所发现的,并且根据,使用“yy”将导致SimpleDateFormat解释相对于某个世纪的缩写年份。它通过将日期调整为创建SimpleDataFormat实例前80年和创建SimpleDataFormat实例后20年

如果您想定义一个日期格式化程序,它接受一个列表或一组模式,而不是调用
return-getDateFormat(locale).parse(text)
当调用其解析方法时,您必须实现CustomDateFormatter,它实现接口
Formatter
,如中所述

模式私有变量不是一个字符串,而是一个字符串列表,您的解析方法与本文中的示例类似


实现中提到的
AnnotationFormatterFactory
,然后您可以将模式列表指定为注释。

在我看来,绑定到
LocalDate
类型属性的spring注释@DateTimeFormat将导致spring选择JodaTime格式化程序,而不是标准格式化程序,否则Spring将无法成功地将任何输入字符串解析为类型为
LocalDate
的对象。此语句是在分析的基础上完成的(请参见方法的实现
getParser(DateTimeFormat注释,类字段类型)

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

的源代码提取(在私有方法中对JodaTime进行模式分析
parsePatternTo(DateTimeFormatterBuilder,字符串模式)
):

案例“y”://年份(编号)
案例“Y”://纪年(编号)
如果(tokenLen==2){
布尔宽容分析=真;
//向前看下一个令牌。
如果(i+1<长度){
indexRef[0]++;
if(isNumericToken(parseToken(pattern,indexRef))){
//如果下一个令牌是数字,则无法支持
//宽松解析,因为它将使用不应该使用的数字。
宽容=错误;
}
indexRef[0]-;
}
//使用与SimpleDataFormat兼容的枢轴。
开关(c){
案例“x”:
appendTwoDigitWeekyear(new DateTime().getWeekyear()-30,lenientParse);
打破
案例“y”:
案例“Y”:
违约:
builder.appendTwoDigitYear(new DateTime().getYear()-30,lenientParse);
打破
}
因此,我们认识到JodaTime将模式表达式“yy”转换为对生成器方法的调用
appendTwoDigitYear()
,参数lenientParse设置为
true
。有趣的是,choosen pivot year偏离了通常的Joda设置(+/-50年),即(-80/+20年)

书中说:

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


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

我认为问题是关于JodaTime的,而不仅仅是
java.util.Date
    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;                    
          }