2011-04-27 88 views
10

我的目標是進行嚴格的解析(例如禁止像'98/99'這樣的日期)。但是,下面的代碼引發與消息無法解析的日期java.text.ParseException:「98/01」如何在本週的第一天在上一年嚴格解析僅有一年和一週數的日期?

SimpleDateFormat sdf = new SimpleDateFormat("yy/ww"); 
sdf.setLenient(false); 
sdf.parse("98/01"); 

這確實是first week of 1998,開始在星期四。但是,一週的解析總是會返回本週的第一天的日期。在那種情況下,它將是12/29/1997。這就是爲什麼會引發異常。

看來這個問題來自於GregorianCalendar類,更具體地說從computeTime()方法,檢查,如果原來的匹配字段的字段外部設置當解析爲不寬鬆

if (!isLenient()) { 
    for (int field = 0; field < FIELD_COUNT; field++) { 
    if (!isExternallySet(field)) { 
     continue; 
    } 

    if (originalFields[field] != internalGet(field)) { 
     // Restore the original field values 
     System.arraycopy(originalFields, 0, fields, 0, fields.length); 
     throw new IllegalArgumentException(getFieldName(field)); 
    } 
    } 
} 

這是一個錯誤?我認爲解析1998/01的確應該返回12/29/1997而不是引發任何異常。但是,您是否知道如何使解析返回01/01/1998而不是(這將是指定年份中每週的第一天)?

+0

你試過「尤達時間」庫嗎?我個人沒有,但是我聽說它優於JDK日期/時間類。 – 2011-04-27 10:28:21

+0

我嘗試過[喬達時間](http://joda-time.sourceforge.net/),但我無法使它工作。 – 2011-04-27 11:02:43

回答

3

我認爲這應該爲你工作(你所需要的庫喬達時間這一點):

public static Date parseYearWeek(String yearWeek) { 
    DateTime dateTime = DateTimeFormat.forPattern("yy/ww").parseDateTime(yearWeek); 

    if (dateTime.getWeekOfWeekyear() == 1 && dateTime.getMonthOfYear() == 12) { 
     dateTime = DateTimeFormat.forPattern("yyyy/mm").parseDateTime((dateTime.getYear() + 1) + "/01"); 
    } 

    return dateTime.toDate(); 
} 
+0

完美。我仍然利用'SimpleDateFormat'解析的優勢,但每當引發'ParseException'時都會使用你的方法。 – 2011-05-06 09:58:33

0

您可以使用日爲基準,減去3天來計算日的日期。 ISO 8601第1周的定義是星期四發生的第一週。 這將消除補償代碼。 下面的代碼會在一週內找到星期一,即使星期一是在「上一年」。

String yearWeek = "201301"; 
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyywwEEE").withLocale(Locale.US); 
DateTime mondayInWeek= fmt.parseDateTime(yearWeek + "Thu").minusDays(3);// ISO 8601 def of week 1 is first week where Thursday occurs 
System.out.println(mondayInWeek); 
相關問題