正确的俄语月份字符串翻译 Java
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26642720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Proper Russian month string translation Java
提问by abhig
I want to convert a Date in to Russian and using the code below
我想将日期转换为俄语并使用下面的代码
SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,locale).format(date);
where locale is of type Locale The problem is months are not parsed correctly . January is coming as "январь" it should be "января" and February is coming as "февраль" should be "февраля"
其中 locale 是 Locale 类型的问题是月份没有正确解析。一月是“январь”,它应该是“января”,二月是“февраль”应该是“февраля”
and so on...
等等...
One idea is to convert incorrect months to proper ones in my logic
一个想法是在我的逻辑中将不正确的月份转换为正确的月份
Is there any thing by which Java do this automatically ?
Java 是否可以自动执行此操作?
Thanks
谢谢
回答by Meno Hochschild
On my JDK-6-installation I can reproduce your problem:
在我的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 offers you a solution.
Java-8 为您提供了一个解决方案。
It seems that the JDK has changed the internal default from "standalone-style" (nominative) to "format-style" (genitive).
JDK 似乎已将内部默认值从“独立样式”(主格)更改为“格式样式”(所有格)。
String date =
DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
.withLocale(new Locale("ru"))
.format(LocalDate.of(2014, 2, 28));
System.out.println(date); // output: 28 февраля 2014 г.
If you need to apply standalone textstyle then you have to set up your own DateTimeFormatterBuilder
which requires a little bit more effort, else TextStyle.FULL
should be the default.
如果您需要应用独立的文本样式,那么您必须设置自己的文本样式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)
Workaround for Java-pre-8 using old style:
使用旧样式的 Java-pre-8 的解决方法:
Define your own text resources (troublesome)!
定义自己的文字资源(麻烦)!
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-Timedoes not offer a good solution in a Java-pre-8 environment because it only delegates to JDK. See also a similar issue on Joda-site.
Joda-Time在 Java-pre-8 环境中没有提供好的解决方案,因为它只委托给 JDK。另请参阅Joda-site上的类似问题。
Finally there is also my library Time4Jwhich can solve the problem like Java-8, but uses its own text resources for Russian and understands both forms (old style and standalone-style), so this is a simple solution for older Java-versions (and will of course not be obsoleted by Java-8 due to many other feature enhancements).
最后还有我的库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 г.
回答by Vitalii Dmitriev
For Java 8you can use a new pattern.
对于Java 8,您可以使用新模式。
In short:
The "LLLL"
pattern will get a Nominativecase:
简而言之:该"LLLL"
模式将获得一个主格:
new SimpleDateFormat("LLLL", Locale.getDefault()).format(date); // январь
The "MMMM"
pattern will return a String
in Genitivecase:
该"MMMM"
模式将String
在Genitive情况下返回 a :
new SimpleDateFormat("MMMM", Locale.getDefault()).format(date); // января
Alternatively, instead of hardcoding Russian months in array (since we have Polish, Ukrainian and other languages), you could use the java.time.Month
enum. It contains both months int
number and String
name.
或者,您可以使用java.time.Month
枚举,而不是在数组中硬编码俄语月份(因为我们有波兰语、乌克兰语和其他语言)。它包含月int
数和String
名称。
回答by CoolMind
While an accepted answer of @Meno Hochschild and https://stackoverflow.com/a/27421103/2914140are correct, I want to add a little.
虽然@Meno Hochschild 和https://stackoverflow.com/a/27421103/2914140的公认答案是正确的,但我想补充一点。
It's enough to set Locale("ru")
, then create and apply sdf.format(date)
.
设置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);
}
But if you want to customize it, I will show a process.
但是如果你想定制它,我会展示一个过程。
After many exceptions I realized that weekdays start not from Monday (see http://jexp.ru/index.php/Java_Tutorial/Data_Type/Date_Format#Change_date_formatting_symbols)!
在经历了许多例外之后,我意识到工作日不是从星期一开始的(参见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
}
回答by maksimov
AFAIK, there's no support for localisation in accusative case in the JDK. I would suggest to use the MEDIUM
date format to work around that if it's suitable:
15 Фев 1999
AFAIK,JDK 中不支持宾格中的本地化。MEDIUM
如果合适,我建议使用日期格式来解决这个问题:
15 Фев 1999
Failing that you may end up having to provide your own localisations for month names.
如果失败,您可能最终不得不为月份名称提供自己的本地化。
回答by M pr
Sorry if my answer would not fully fit the question, but still' I'd like to share my way of solving the issue with translating the Date into Russian format.
抱歉,如果我的回答不完全符合问题,但我仍然想分享我通过将日期翻译成俄语格式来解决问题的方法。
Had big headache with dealing with DateTime Locales and so on, I started to simply translate Weekdays and Months in String representation of original DateTime.
对处理日期时间语言环境等感到非常头疼,我开始简单地将工作日和月份转换为原始日期时间的字符串表示形式。
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;
}