2013-02-21 110 views
4

我正在尋找一個java庫,可以解析一個字符串到一個POJO沒有指定的格式。我研究了POjava。有沒有其他的庫可以做類似的事情?自動日期/時間分析器沒有指定格式

DateTime dateTime = DateTimeParser.parse("21/02/13"); 

//If unclear use the cultural information passed 
DateTime dateTime = DateTimeParser.parse("01/02/13", new Locale("en-us")); 

//Should also work with time zones 
DateTime dateTime = DateTimeParser.parse("2011/12/13T14:15:16+01:00"); 

我發現同樣的問題Intelligent date/time parser for Java以下鏈接,但不是非常有用的答案。 Joda和JChronic都不做我想要的。糾正我,如果我錯了。

更新:

我之所以說喬達並沒有解決我的目的是,喬達預計ISO8601格式或您指定像「年月日」任意格式的解析字符串。由於我需要處理多種格式,因此我無法對此格式進行硬編碼。

我有一個針對美國或歐洲日期格式(即mm/dd/yy或dd/mm/yy)消除歧義的解決方案。假設我可以訪問日期的時區,我可以確定它是美式還是歐式格式?有人能告訴我如何做到這一點嗎?谷歌搜索,但沒有發現。

+3

你會想到的第一個版本與'6月5日/ 2013'嗎?無論你選擇什麼,你都會爲地球的相當大的一部分錯誤。 – 2013-02-21 19:02:41

+0

你看喬達時間嗎? – 2013-02-21 19:03:57

+0

如果第一行有歧義,請使用默認文化信息,除非在第二行代碼中指定了一個文字信息 – saravanan07 2013-02-21 19:05:53

回答

3

我找到了我的問題的答案。我用這個特殊的庫POjava。這page解釋瞭如何格式化日期+時間字符串,而不指定任何格式。但是,爲了使圖書館正常工作,您必須指定日期排序,例如Day,然後是Month或Month,然後是Day。

8

問題是,有一些格式,不能被猜測是正確的。

一個簡單的例子是01/02/2013。這是2月1日還是1月2日?甚至更糟:01/02/09

兩種格式都存在。 (謝謝你,英國和美國!)

所以任何格式猜測者將不得不依靠這些格式的運氣,或故意故意爲這些格式。

python模塊dateutil.parser可以作爲盡力而爲解析器的一個例子。對不起,我不知道一個Java等價物。但你可能想看看Joda Time

http://labix.org/python-dateutil#head-b95ce2094d189a89f80f5ae52a05b4ab7b41af47

它實際上有參數dayfirstyearfirst

然後有一個Perl模塊:

https://metacpan.org/pod/Time::ParseDate

你也許能夠使用的優先級列表從該模塊。盲目嘗試一些模式的速度並不是很快(優化的詞法分析器會更快),但除非您猜測數百萬條記錄的格式,否則對您而言可能已經足夠好了。

+0

如果第一行有歧義(請參閱原始問題中的代碼)使用默認的文化信息,除非在第二個代碼行中指定了一個。我可以從任何圖書館獲得這種情報嗎? – saravanan07 2013-02-21 19:36:49

0

對此沒有神奇的解決方案。記住日期/時間格式也可以取決於您的區域設置。

實際上,您可以做的最好的是定義一個格式列表,然後逐個「嘗試」它們,直到找到合適的一個(或者沒有)。

private static final FORMAT_1 = "MM/dd/yyyy'T'HH:mm:ss.SSS" 
private static final FORMAT_2 = "MM/dd/yyyy'T'HH:mm:ss" 
private static final FORMAT_3 = "MM/dd/yyyy" 

記得在java中使用日期/時間對象時要考慮線程的安全性。我有一個類正在做這種名爲「ThreadSafeDateTimeFormatter」的東西。

祝你好運!

0

由於我沒有找到方便的解決方案,我寫了一個簡單的靜態工具方法幫助我。如果添加更多格式,將集合中的格式封裝並迭代它可以使事情變得更簡單。

public static Date returnDateFromDateString(String propValue) throws Exception { 

    SimpleDateFormat sdfFormat1 = new SimpleDateFormat(IDateFConstants.DATE_STRING_FORMAT_1); 
    SimpleDateFormat sdfFormat2 = new SimpleDateFormat(IDateFConstants.DATE_STRING_FORMAT_2); 
    SimpleDateFormat sdfISO8601 = new SimpleDateFormat(IDateFConstants.DATE_STRING_ISO_8601); 

    try { 
     return sdfFormat1.parse(propValue); 
    } catch (ParseException e) { } 

    try { 
     return sdfFormat2.parse(propValue); 
    } catch (ParseException e) { } 

    try { 
     return sdfISO8601.parse(propValue); 
    } catch (ParseException e) { } 

    throw new Exception(IDateFConstants.DATE_FORMAT_ERROR); 
} 

其中IDateFConstants看起來像

public interface IDateFConstants { 

public static final String DATE_STRING_ISO_8601 = "yyyy-MM-dd'T'HH:mm:ss"; 
public static final String DATE_STRING_FORMAT_1 = "dd.MM.yyyy"; 
public static final String DATE_STRING_FORMAT_2 = "dd.MM.yyyy HH:mm:ss"; 

public static final String DATE_FORMAT_ERROR = "Date string wasn't" + 
              + "formatted in known formats"; 

}