2017-04-26 160 views
10

我工作的阿拉伯文網絡監控項目,我想字符串轉換日期像這樣的:如何將阿拉伯字符串日期轉換爲java 8日期對象?

الاثنين 24 أبريل 2017 - 15:00 

到Java 8日期對象。我怎樣才能做到這一點?

+0

您是否嘗試過使用語言環境來使用阿拉伯語的國家?請參閱:http://stackoverflow.com/questions/29154887/setting-arabic-numbering-system-locale-doesnt-show-arabic-numbers/29155743#29155743 – slim

+1

這是不是已經解決了34搜索時已發現[搜索「java arabic date」](http://stackoverflow.com/search?q=java+arabic+date)? –

回答

0

一種解決方案可能是翻譯的日期爲英語和解析它,然後:

private final static Map<String, Integer> monthMapping = new HashMap<>(); 
static { 
    // list of all month. 
    monthMapping.put("أبريل", "4"); 
} 


public Date fromArabicToDate(String arabicInput) throws ParseException { 
    String[] parts = arabicInput.split(" "); 
    if (parts.length != 4) 
     throw new IllegalArgumentException(); 

    String dateInput = parts[0] + "-" + monthMapping.get(parts[1]) + "-" + parts[2]; 
    SimpleDateFormat parser = new SimpleDateFormat("YYYY-MM-DD"); 
    return parser.parse(dateInput); 
} 

我試過一個月來複制,但我不相信我已經正確的。解析時切換put的參數。你可以看看Joda-Time。也許他們有一個解決方案。這是mentioned here

+1

哦......過時的信息。你永遠不要停止學習。謝謝@Hulk。這是我心中的某個地方。我發現它在相同的地方,但它已超過4年:http://stackoverflow.com/a/14439397/2097191(我改變了我的答案) – Obenland

+0

你所指的答案似乎是關於[SimpleDateFormat'的一個特定構造函數](https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html#SimpleDateFormat-java.lang.String-java.util.Locale- ):「使用給定的模式和默認的FORMAT語言環境的默認日期格式符號構造一個SimpleDateFormat注意:此構造函數可能不支持所有語言環境,爲了全面覆蓋,請使用DateFormat類中的工廠方法。 – Hulk

2

我不知道阿拉伯語足夠了解阿拉伯語格式的日期。然而這段代碼:

Locale arabicLocale = new Locale.Builder().setLanguageTag("ar-SA-u-nu-arab").build(); 

LocalDate date = LocalDate.now(); 
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(arabicLocale); 

String formatted = date.format(formatter); 
System.out.println(formatted); 
System.out.println(formatter.parse(formatted)); 

息率這樣的輸出:

26 أبريل, 2017 
{},ISO resolved to 2017-04-26 

創建Locale是一個答案Setting Arabic numbering system locale doesn't show Arabic numbers

您可以定義自己的FormatStyle微調此格式的代碼。

4

編輯:以感謝苗條和梅諾Hochschild上尋找靈感:

String dateTimeString = "الاثنين 24 أبريل 2017 - 15:00"; 

DateTimeFormatter formatter 
     = DateTimeFormatter.ofPattern("EEEE d MMMM uuuu - HH:mm", new Locale("ar")); 
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter); 
System.out.println(dateTime); 

此打印:

2017-04-24T15:00 
+1

只需構造不帶nu擴展名的語言環境。它沒有工作,並應該失敗,你的nu延伸(但不),看到我的答案。 –

+0

非常感謝,@MenoHochschild。在我的電腦上,即使是'新的Locale(「ar」)'也能工作,所以我把它放在了複雜的語言標記中。 –

0

解析字符串時,假定日期需要,您必須指定字符集解析將始終以您提供的格式工作:

public static Date getDate(String strDate) throws Exception{ 
    strDate=new String(strDate.getBytes(),"UTF-8"); 

    Map<String, Integer> months = new HashMap<>(); 

    String JAN = new String("يناير".getBytes(), "UTF-8"); 
    String FEB = new String("فبراير".getBytes(), "UTF-8"); 
    String MAR = new String("مارس".getBytes(), "UTF-8"); 
    String APR = new String("أبريل".getBytes(), "UTF-8"); 
    String APR_bis = new String("ابريل".getBytes(), "UTF-8"); 
    String MAY = new String("ماي".getBytes(), "UTF-8"); 
    String JUN = new String("بونيو".getBytes(), "UTF-8"); 
    String JUN_bis = new String("يونيه".getBytes(), "UTF-8"); 
    String JUL = new String("يوليوز".getBytes(), "UTF-8"); 
    String AUG = new String("غشت".getBytes(), "UTF-8"); 
    String SEP = new String("شتنبر".getBytes(), "UTF-8"); 
    String SEP_bis = new String("سبتمبر".getBytes(), "UTF-8"); 
    String OCT = new String("أكتوبر".getBytes(), "UTF-8"); 
    String OCT_bis = new String("اكتوبر".getBytes(), "UTF-8"); 
    String NOV = new String("نونبر".getBytes(), "UTF-8"); 
    String NOV_bis = new String("نوفمبر".getBytes(), "UTF-8"); 
    String DEC = new String("دجنبر".getBytes(), "UTF-8"); 
    String DEC_bis = new String("ديسمبر".getBytes(), "UTF-8"); 



    months.put(JAN, 0); 
    months.put(FEB, 1); 
    months.put(MAR, 2); 
    months.put(APR, 3); 
    months.put(APR_bis, 3); 
    months.put(MAY, 4); 
    months.put(JUN, 5); 
    months.put(JUN_bis, 5); 
    months.put(JUL, 6); 
    months.put(AUG, 7); 
    months.put(SEP, 8); 
    months.put(SEP_bis, 8); 
    months.put(OCT, 9); 
    months.put(OCT_bis, 9); 
    months.put(NOV, 10); 
    months.put(NOV_bis, 10); 
    months.put(DEC, 11); 
    months.put(DEC_bis, 11); 


    StringTokenizer stringTokenizer = new StringTokenizer(strDate); 

    Calendar calendar = Calendar.getInstance(); 


    while(stringTokenizer.hasMoreElements()) { 

     stringTokenizer.nextElement();// to skip the first string which is the name of the day 

     int day = Integer.parseInt(stringTokenizer.nextElement().toString().trim()); 

     String strMonth = stringTokenizer.nextElement().toString().trim(); 

     int month = months.get(strMonth); 

     int year = Integer.parseInt(stringTokenizer.nextElement().toString().trim()); 

     calendar.set(year, month, day); 


    } 
    return calendar.getTime(); 

} 

它給出了這個o輸出:

Fri Oct 20 15:26:47 WEST 2017 
+0

我錯過了您的字符串轉換中的一點。在我的計算機上'new String(「يناير」。getBytes(),「UTF-8」)'產生與'يناير''相同的字符串。所有其他月份名稱都一樣。在具有不同默認字符集的計算機上,結果可能會有所不同。 –

+0

是啊@ OleV.V。它被添加來指定想要的字符集是'UTF-8' –

3

@Ole和@slim的答案正在工作,但不是因爲他們認爲的原因。

首先觀察 - 怒江擴展是不需要給出的例子:

OLES建議也將工作的語言環境new Locale("ar", "SA"),而不是Locale.forLanguageTag("ar-SA-u-nu-arab")。那麼這裏的unicode-nu-extension是什麼呢?沒有。下一個問題:

nu-extension應該在這裏做什麼?

nu-code-word-word「alla」是specified by the unicode consortium以產生阿拉伯數字。但是要解析的輸入只有西方數字0-9(歷史上它們被阿拉伯人取代,並被指定爲代碼字「latn」 - 順便提一句,用法不當)。因此,如果NU-擴展已經真的在這裏完成了它的任務,然後解析竟沒因爲arabic-indic digits不是0-9而是:

顯然,Java-8中的新時間API不支持nu-extension。

SimpleDateFormat是否支持nu-extension?

使用下面的代碼的調試,我發現,NU-擴展僅支持泰國的數字(見java.util.Locale類的官方的javadoc而不是阿拉伯語,印度語數字:

SimpleDateFormat sdf = 
    new SimpleDateFormat("EEEE d MMMM yyyy - HH:mm", Locale.forLanguageTag("ar-SA-nu-arab")); 
Date d = sdf.parse(dateTimeString); 
System.out.println(d); 
String formatted = sdf.format(d); 
System.out.println(formatted); 
System.out.println(sdf.format(d).equals(dateTimeString)); 

sdf = new SimpleDateFormat("EEEE d MMMM uuuu - HH:mm", Locale.forLanguageTag("ar-SA-u-nu-thai")); 
String thai = sdf.format(d); 
System.out.println("u-nu-thai: " + thai); 

我承擔類DateTimeFormatter的Java-8還支持泰文數字

結論:

忘記NU-的擴展名常量通過老式的方式來擴展語言環境,而不需要unicode擴展,並採用這種方式來調整Oles的答案。它的工作原理是因爲你的輸入只有西方數字0-9。

對於包括用於各種編號系統的nu-extension(如果有這樣的輸入)在內的廣泛i18n支持,您可以考慮外部庫(例如ICU4J或我的lib Time4J)。