适当的俄语月字符串翻译Java

时间:2014-10-29 23:55:11

标签: java date localization

我想将日期转换为俄语并使用以下代码

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

其中locale的类型为Locale 问题是几个月没有正确解析。 1月将以“январь”出现,它应该是“января”而2月即将到来,因为“февраль”应该是“февраля”

依旧......

一个想法是在我的逻辑

中将不正确的月份转换为正确的月份

Java会自动执行此操作吗?

由于

6 个答案:

答案 0 :(得分:21)

在我的 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已将内部默认值从“独立式”(主格式)更改为“格式式”(genitive)。

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

如果您需要应用独立的textstyle,那么您必须设置自己的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-pre-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 г.

Joda-Time 在Java-pre-8环境中不提供良好的解决方案,因为它只委托给JDK。另请参阅Joda-site上的类似问题。

最后还有我的库 Time4J 可以解决像Java-8这样的问题,但是使用自己的俄语文本资源并理解这两种形式(旧式和独立式) ),这对于较旧的Java版本来说是一个简单的解决方案(当然,由于许多其他功能增强,Java-8当然不会废弃它)。

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

答案 1 :(得分:10)

对于 Java 8 ,您可以使用新模式。

简而言之: "LLLL"模式将获得 Nominative 案例:

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

"MMMM"模式将在 Genitive 案例中返回String

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

或者,您可以使用java.time.Month枚举,而不是硬编码俄语月份(因为我们有波兰语,乌克兰语和其他语言)。它包含月份int号码和String名称。

答案 2 :(得分:5)

虽然@Meno Hochschild和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
}

答案 3 :(得分:1)

AFAIK,在JDK的指控案例中不支持本地化。我建议使用MEDIUM日期格式来解决这个问题,如果它适合: 15 Фев 1999

如果不这样做,您最终可能需要为月份名称提供自己的本地化。

答案 4 :(得分:1)

在我的任务中,我应该只从整数中获取一个月,所以这段代码非常适合我:

int month=5;//for example
Month.of(month).getDisplayName(TextStyle.FULL_STANDALONE, new Locale("ru"));

答案 5 :(得分:0)

很抱歉,如果我的回答不完全适合这个问题,但仍然是'我想通过将日期翻译成俄文格式来分享我解决问题的方法。

在处理DateTime Locales等问题时非常头疼,我开始简单地在原始DateTime的String表示中翻译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;
}