2014-10-29 45 views
10

我想一個日期在轉換爲俄語和使用下面正確俄羅斯本月字符串翻譯的Java

SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,locale).format(date); 

代碼其中locale是語言環境類型的 問題是個不能正確解析的。一月即將爲「январь」應該是「января」和二月即將爲「февраль」應爲「февраля」

等等...

一個想法是不正確的月轉換爲正確的人在我的邏輯

是否有任何事情由Java自動執行此操作?

謝謝

回答

18

在我JDK-6 - 安裝我可以重現你的問題:

Date jud = new SimpleDateFormat("yyyy-MM-dd").parse("2014-02-28"); 
String month = 
    DateFormat.getDateInstance(SimpleDateFormat.LONG, new Locale("ru")).format(jud); 
System.out.println(month); // output: 28 Февраль 2014 г. 

的Java-8爲您提供了一個解決方案。

看來,JDK已將內部默認從「獨立式」(主格式)改爲「格式式」(格格式)。

String date = 
    DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL) 
    .withLocale(new Locale("ru")) 
    .format(LocalDate.of(2014, 2, 28)); 
System.out.println(date); // output: 28 февраля 2014 г. 

如果您需要申請獨立的文本樣式,那麼你必須建立自己的DateTimeFormatterBuilder這需要多一點點的努力,否則TextStyle.FULL應該是默認的。

String m = Month.FEBRUARY.getDisplayName(TextStyle.FULL , new Locale("ru")); 
// февраля (first and last char are different) 

String s = Month.FEBRUARY.getDisplayName(TextStyle.FULL_STANDALONE , new Locale("ru")); 
// Февраль (this style can be used in DateTimeFormatterBuilder for the month field, too) 

解決方法Java的前8使用舊的樣式:

定義自己的文本資源(麻煩)!

Locale russian = new Locale("ru"); 
String[] newMonths = { 
    "января", "февраля", "марта", "апреля", "мая", "июня", 
    "июля", "августа", "сентября", "октября", "ноября", "декабря"}; 
DateFormatSymbols dfs = DateFormatSymbols.getInstance(russian); 
dfs.setMonths(newMonths); 
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, russian); 
SimpleDateFormat sdf = (SimpleDateFormat) df; 
sdf.setDateFormatSymbols(dfs); 

Date jud = new SimpleDateFormat("yyyy-MM-dd").parse("2014-02-28"); 
String month = sdf.format(jud); 
System.out.println(month); // output: 28 февраля 2014 г. 

喬達時間沒有提供在Java的前8環境,因爲它只能委託給JDK一個很好的解決方案。請參閱Joda-site上的類似問題。

最後還有我的圖書館Time4J可以解決像Java-8的問題,但使用它自己的文本資源,俄羅斯和理解兩種形式(舊風格和獨立式的),所以這是一個簡單的解決方案對於較老的Java版本(當然,由於許多其他功能增強,Java-8也不會過時)。

System.out.println(
    PlainDate.formatter(DisplayMode.FULL, new Locale("ru")).format(
     PlainDate.of(2014, Month.FEBRUARY, 28) 
    ) 
); // output: 28 февраля 2014 г. 
1

AFAIK,在JDK中不支持本地化的情況。我會建議使用MEDIUM日期格式來解決,如果它是合適的: 15 Фев 1999

如果做不到這一點,你可能最終不得不提供自己的本地化月份名稱。

+0

如果二月份俄羅斯標籤的第一個字符在兩種情況下略有不同,那麼只選擇縮寫形式不能解決問題。 – 2014-10-30 08:26:21

+0

這不是第一個字符,它是最後一個。如果變化改變了第一個字母,俄語將會是一個完全瘋狂的瘋狂語言! :-) – maksimov 2014-10-30 12:17:26

+0

請再仔細看看角色。第一個字符是不同的(根據我的分析,代碼點1092與1060)雖然看起來非常相似。我相信這是關於大寫,但不太確定(俄語不是我的語言)。由於變形,最後的字符是不同的。在這裏,我們都同意。 – 2014-10-30 17:59:46

0

對不起,如果我的答案不能完全符合問題,但仍'我想分享我的方式來解決日期轉換成俄羅斯格式的問題。

對於處理DateTime Locales等等,我很頭痛,於是我開始簡單地翻譯原始DateTime的字符串表示中的Weekdays和Months。

String originalDate = "Tue, 22 Nov 2016 01:03:00 +0300"; 
Log.d("Date in Russian",convertStringDateToRussian(linkText)); 

public String convertStringDateToRussian(String mDate) { 

    String[] engWeek = { 
      "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 
      "Sun"}; 
    String[] ruWeek = { 
      "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", 
      "Воскресенье"}; 
    String[] engMonths = { 
      "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 
    String[] ruMonths = { 
      "января", "февраля", "марта", "апреля", "мая", "июня", 
      "июля", "августа", "сентября", "октября", "ноября", "декабря"}; 
    for (
      int t = 0; 
      t < engWeek.length; t++) 

    { 
     if (mDate.contains(engWeek[t])) { 
      mDate = mDate.replace(engWeek[t], ruWeek[t]); 
      break; 
     } 
    } 

    for (
      int t = 0; 
      t < engMonths.length; t++) 

    { 
     if (mDate.contains(engMonths[t])) { 
      mDate = mDate.replace(engMonths[t], ruMonths[t]); 
      break; 
     } 
    } 

    return mDate; 
} 
+0

謝謝,你選擇了從英文到俄文的翻譯方式。這是一種不同的方法,但可以使用。但可能是一種可以接受的語言(Java-8和Java-pre-8變體)可以工作。另外不要忘記名稱的小寫:不是「Февраля」,而是「февраля」。 – CoolMind 2016-12-07 09:21:39

+0

感謝您的回覆。這個解決方案在Android中可能更有用,因爲我根本無法爲DateTime創建「RU」語言環境。 – 2016-12-12 12:57:48

+0

如果你想使用Android,我在這個主題中增加了一個解決方案。 – CoolMind 2016-12-12 15:51:27

1

雖然@Meno爾德和https://stackoverflow.com/a/27421103/2914140的接受的答案是正確的,我想補充一點。

這足以設置Locale("ru"),然後創建並應用sdf.format(date)

public static String formatDate(long date, String format) { 
    Locale locale = new Locale("ru"); 
    SimpleDateFormat sdf = new SimpleDateFormat(format, locale); 
    return sdf.format(date); 
} 

但是,如果你想定製它,我會顯示一個過程。

經過很多例外,我意識到平日不是從星期一開始(見http://jexp.ru/index.php/Java_Tutorial/Data_Type/Date_Format#Change_date_formatting_symbols)!

public static String formatDate(long date, String format) { 
    //Locale locale = new Locale("fr"); 
    Locale locale = new Locale("ru"); 
    DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale); 
    String[] months = { 
      "января", "февраля", "марта", "апреля", "мая", "июня", 
      "июля", "августа", "сентября", "октября", "ноября", "декабря"}; 
    String[] shortMonths = { 
      "янв", "фев", "мар", "апр", "май", "июн", 
      "июл", "авг", "сен", "окт", "ноя", "дек"}; 
    dfs.setMonths(months); 
    dfs.setShortMonths(shortMonths); 
    String[] weekdays = {"", "Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"}; 
    String[] shortWeekdays = {"", "вс", "пн", "вт", "ср", "чт", "пт", "сб"}; 
    dfs.setWeekdays(weekdays); 
    dfs.setShortWeekdays(shortWeekdays); 

    SimpleDateFormat sdf = new SimpleDateFormat(format, locale); 
    sdf.setDateFormatSymbols(dfs); 
    return sdf.format(date); // пт, 09 декабря 2016 
} 
4

對於的Java 8你可以使用一個新的模式。

簡而言之: 的"LLLL"格局將得到記名情況:

new SimpleDateFormat("LLLL", Locale.getDefault()).format(date); // январь 

"MMMM"模式將返回String所有格情況:

new SimpleDateFormat("MMMM", Locale.getDefault()).format(date); // января 

或者,而不是硬編碼俄羅斯月陣(因爲我們有波蘭語,烏克蘭語和其他語言),您可以使用java.time.Month枚舉。它包含兩個月份int號碼和String名稱。