正确的俄语月份字符串翻译 Java

2022-09-02 14:22:58

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

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

其中 locale 的类型 Locale 问题是月份未正确解析 。一月即将到来,因为“январь”应该是“января”,二月即将到来,因为“февраль”应该是“февраля”

等等...

一个想法是在我的逻辑中将不正确的月份转换为适当的月份

Java会自动做到这一点吗?

谢谢


答案 1

在我的 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 г.

如果你需要应用独立的文本样式,那么你必须设置自己的文本样式,这需要更多的努力,否则应该是默认的。DateTimeFormatterBuilderTextStyle.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网站上的类似问题。

最后还有我的库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 г.

答案 2

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

简而言之:该模式将获得一个主格"LLLL"

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

该模式将返回一个 in Genitive 大小写:"MMMM"String

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

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