2014-02-12 14 views
7

綁定日期我用來支持Java DateJoda Localdate模式中使用Spring DateTimeFormat pattern屬性這樣多模式

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

約束力,但我需要支持兩個日期的模式,例如:

如果用戶輸入31/12/199931/12/99,那麼它們都可以綁定到相同的值31/12/1999。是否可以爲@DateTimeFormat定義兩種模式?

編輯:

我試着模式改變爲

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

而且我發現它可以處理這兩種情況下(例如,當用戶輸入31/12/199931/12/99)都綁定到31/12/1999 。任何意見?

回答

4

在我看來,綁定到類型爲LocalDate的屬性的Spring註釋@DateTimeFormat將導致Spring選擇JodaTime-Formatter,而不是標準格式化程序,否則Spring將無法成功地將任何輸入字符串解析爲對象LocalDate。該聲明在Spring source code的分析上完成(參見方法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;      
      } 

因此,我們認識到,JodaTime轉換模式表達式「YY」的呼叫Builder的方法appendTwoDigitYear()與參數lenientParse設置爲true。有趣的是,選擇的關鍵年偏離了通常的Joda設置(+/- 50年),即(-80/+ 20年)。

Javadoc of mentioned builder-method這是說:

「lenientParse - 如果爲true,如果數字計數而不是兩個,它被視爲一個絕對的一年」

這充分解釋了爲什麼「dd.mm. yy「也可以解析兩位數年份和四位數年份。

1

Spring的當前實現DateFormatter只允許設置一個模式。

當您發現編輯並根據Java Documentation for SimpleDateFormat,使用「yy」導致SimpleDateFormat解釋相對於某個世紀的縮寫年份。它通過將日期調整爲在創建SimpleDateFormat實例之前的80年之內和20年之後執行此操作。

如果要定義一個接受列表或一組模式和而不是調用return getDateFormat(locale).parse(text);當它的解析方法被調用時,你就必須實現它實現作爲Spring 3 Field Formatting提到的接口Formatter<T>一個CustomDateFormatter一個DateFormatter。

而不是模式私有變量的單個字符串,你會有一個字符串列表,你的解析方法將類似於這個StackOverflow Question的例子。

執行AnnotationFormatterFactorySpring 3 Field Formatting所述,然後您可以指定您的模式列表作爲註釋。

+0

我認爲問題是關於JodaTime,不僅是'java.util.Date'。 –