2009-10-06 113 views
2

所以我有一個問題,解析日期,使用JodaTime年表IslamicChronology所以寫了一個小例子來演示我的問題。Joda時間錯誤或我的錯誤? (Java Joda時間日期作爲字符串解析)

下面的代碼:

import org.joda.time.Chronology; 
import org.joda.time.format.DateTimeFormatter; 
import org.joda.time.format.DateTimeFormat; 
import org.joda.time.chrono.IslamicChronology; 

import java.util.Date; 

/** 
* Test 
*/ 
public class Test 
{ 
    public static void main(String[] args) 
    { 
     Date now = new Date(); 

     String format = "dd MMM yyyy"; 
     Chronology calendarSystem = IslamicChronology.getInstance(); 
     DateTimeFormatter formatter = DateTimeFormat.forPattern(format).withChronology(calendarSystem); 

     String nowAsString = formatter.print(now.getTime()); 

     System.out.println("nowAsString = " + nowAsString); 

     long parsedNowTs = formatter.parseMillis(nowAsString); 

     String parsedNowTsAsString = formatter.print(parsedNowTs); 
    } 
} 

和輸出:

nowAsString = 16 10 1430 
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "16 10 1430" is malformed at "10 1430" 
    at org.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:634) 
    at test.Test.main(Test.java:40) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    ... 

我想的問題是,一個月的名字是數字,但我說的對?任何人有任何建議?如果年代學是格雷戈裏這不能被重建。

在此先感謝。

回答

7

如果任何人的興趣......我發現周圍的工作:

  • 創建一個新的類如IslamicChronologyWithNames,其代表包org.joda.time中的IslamicChronology的實例。DateTimeZone
  • 修改一種方法; assemble(Fields fields):調用該委託的方法,然後設置fields.monthOfYear(也可能是星期幾)到您的BasicMonthOfYearDateTimeField
  • 自己的子類則BasicMonthOfYearDateTimeField子類可以在屬性文件名查找月(或一天的,如果星期幾?)名稱。子類需要在包org.joda.time.chrono能夠延伸BasicMonthOfYearDateTimeField

仍存在喬達時間似乎調用諸如getAsText(int fieldValue, Locale locale)子類的方法之前,以驗證您解析日期的問題,因爲它沒有一個月的名字,你的類返回的知識,驗證失敗,因此永遠不會調用方法。我的解決方法是在這個類中有一個靜態方法,它將日期轉換爲帶有伊斯蘭月份名稱的字符串,並將日期轉換爲格式爲英文月份名稱的字符串。因此,在致電parseDateTime()之前,請調用靜態方法,然後日期字符串通過驗證。然後,而不是在convertText()方法處理伊斯蘭月份名稱,使用默認的陽曆實現你的子類中:

protected int convertText(String text, Locale locale) 
{ 
    return GJLocaleSymbols.forLocale(locale).monthOfYearTextToValue(text); 
} 

這應該工作!希望對有同樣問題的任何人都有意義。

2

您已將格式指定爲dd MMM yyyy;根據API,這意味着您需要以縮略字符串形式提供月份(在本例中爲「Oct」)。如果格式爲dd MM yyyy,那麼您傳入的輸入將正確解析。

編輯:看來我錯過了你的觀點。你發現的是對於給定的格式,其中的情況下,

long input = ...; // whatever 
formatter.parseMillis(formatter.print(input)); 

被拋出異常。雖然我看不到任何明確的保證這應該總是工作,我當然期望是這樣的 - 是的,我會支持你的說法,這是在喬達本身可能的錯誤。

至少,如果這是預期的行爲,應該有一些更清楚的跡象表明它可能發生。

+1

但是我提供給格式化是excatly什麼擺在首位創建的格式...所以我的理解是,JodaTime doen't知道第10個月(的Shawwal)的縮寫字符串格式是如此的默認使用它的號碼。然後,我會期待解析完全以相反的方式進行;它會檢查是否具有伊斯蘭年表的縮寫月份名稱,如果不是,則預計該月份是數字。或者我誤解了你在說什麼? – 2009-10-06 14:43:15

5

格式模板中的MMM指示縮寫的月份名稱。數字月份索引應用MM表示。

在閱讀您對dtsazza的回答的評論後,我第一次意識到您的實際問題。 :)

我已經看了JODA的源代碼,它似乎好像支持伊斯蘭時尚是相當破碎。首先,格式化程序不支持月份名稱,以便將MMM和MMMM格式設置爲月份編號,但根據DateTimeFormat文檔,MMM應使用縮寫月份名稱,MMMM使用縮寫月份名稱。

代碼示例的一個問題是parseMillis始終使用ISO年代表,儘管格式化程序已配置爲其他年代表。這也在API文檔中提到,雖然不是特別直觀。

如果我將parseMillis替換爲parseDateTime,我會期望使用年表來解析(至少文檔是這麼說的),但是看起來好像實現忽略了配置的年代表並繼續使用ISO年代表以及。

+0

感謝您的回覆......我一直在調試它,但不幸的是,大多數調試信息對我來說是無法獲得的。我雖然可以看到的是公曆系統使用JDK的DateFormatSymbols類,但伊斯蘭跳過了這一切。但是什麼我無法看到的是在時間順序決定了它是如何查找月/日的名稱是什麼點。你有什麼想法嗎?或知道的方式,我可以同時提高分析和伊斯蘭日期打印? – 2009-10-07 08:13:38