Proper Russian month string translation Java

后端 未结 5 1801
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-09 10:53

I want to convert a Date in to Russian and using the code below

SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,locale).format(date);
<
相关标签:
5条回答
  • 2020-12-09 11:41

    For Java 8 you can use a new pattern.

    In short: The "LLLL" pattern will get a Nominative case:

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

    The "MMMM" pattern will return a String in Genitive case:

    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.

    0 讨论(0)
  • 2020-12-09 11:45

    While an accepted answer of @Meno Hochschild and https://stackoverflow.com/a/27421103/2914140 are correct, I want to add a little.

    It's enough to set Locale("ru"), then create and apply 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)!

    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
    }
    
    0 讨论(0)
  • 2020-12-09 11:48

    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

    Failing that you may end up having to provide your own localisations for month names.

    0 讨论(0)
  • 2020-12-09 11:49

    On my JDK-6-installation I can reproduce your problem:

    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.

    It seems that the JDK has changed the internal default from "standalone-style" (nominative) to "format-style" (genitive).

    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.

    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:

    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-Time does 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.

    Finally there is also my library Time4J which 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).

    System.out.println(
        ChronoFormatter.ofDateStyle(DisplayMode.FULL, new Locale("ru")).format(
            PlainDate.of(2014, Month.FEBRUARY, 28)
        )
    ); // output: 28 февраля 2014 г.
    
    0 讨论(0)
  • 2020-12-09 11:49

    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;
    }
    
    0 讨论(0)
提交回复
热议问题