Spring 多模式上的绑定日期
我以前使用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
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;
}