2014-10-29 11 views
10

voglio convertire una data data al russo e usando il codice seguentecorretta russo traduzione mese stringa Java

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

dove locale è di tipo Locale Il problema è mesi non vengono analizzati correttamente. Gennaio è venuta come "январь" dovrebbe essere "января" e febbraio è in arrivo come "февраль" dovrebbe essere "февраля"

e così via ...

Un'idea è quella di convertire mesi non corretti a quelli corretti nella mia logica

C'è qualche cosa in cui Java lo fa automaticamente?

Grazie

risposta

18

Sul mio JDK-6 -INSTALLAZIONE posso riprodurre il problema:

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 vi offre una soluzione.

Sembra che il JDK abbia cambiato il default interno da "standalone-style" (nominativo) a "format-style" (genitivo).

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

Se è necessario applicare textstyle standalone poi si deve impostare il proprio DateTimeFormatterBuilder che richiede un po 'più di sforzo, altrimenti TextStyle.FULL dovrebbe essere il 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) 

Soluzione per Java-pre-8 utilizzando vecchio stile:

definire il proprio risorse di testo (fastidioso)!

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 non offre una buona soluzione in un ambiente Java-pre-8 perchè solo i delegati al JDK. Vedi anche un problema simile su Joda-site.

Infine c'è anche la mia libreria Time4J che può risolvere il problema come Java-8, ma utilizza le proprie risorse di testo per il russo e capisce entrambe le forme (stile vecchio e standalone-stile), quindi questa è una soluzione semplice per versioni precedenti di Java (e ovviamente non sarà reso obsoleto da Java-8 a causa di molti altri miglioramenti delle funzionalità).

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

per quanto ne so, non c'è alcun supporto per la localizzazione in caso accusativo nel JDK. Vorrei suggerire di utilizzare il formato MEDIUM data per aggirare che se è adatto: 15 Фев 1999

In mancanza di questo si può finire per dover fornire i propri localizzazioni per nomi dei mesi.

+0

Scegliere solo la forma abbreviata non può risolvere il problema se il primo carattere dell'etichetta russa per febbraio è leggermente diverso per entrambi i casi. –

+0

Non è il primo personaggio, è l'ultimo. Il russo sarebbe stato un linguaggio completamente pazzo se le flessioni cambiassero la prima lettera! :-) – maksimov

+0

Per favore, guarda di nuovo i personaggi. Il primo carattere è diverso (codice 1092 contro 1060 secondo la mia analisi), anche se sembra molto simile a prima vista. Credo che riguardi la capitalizzazione, ma non ne sono sicuro (il russo non è la mia lingua). E l'ultimo carattere è diverso a causa dell'inflessione. Qui siamo entrambi d'accordo. –

0

Scusate se la mia risposta non si adatterebbe perfettamente la questione, ma ancora' mi piacerebbe condividere il mio modo di risolvere la questione con la traduzione del Data in formato russo.

Aveva grossi problemi con la gestione di DateTime Locales e così via, ho iniziato a tradurre semplicemente i giorni feriali e i mesi in rappresentazione in formato stringa di DateTime originale.

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

Grazie, hai scelto una via di traduzione dall'inglese al russo. È un metodo diverso, tuttavia può essere utilizzato. Ma probabilmente un linguaggio accettato (varianti Java-8 e Java-pre-8) funzionerebbe. Inoltre, non dimenticare di minuscole nomi: non "Февраля", ma "февраля". – CoolMind

+0

Grazie per la risposta. Questa soluzione potrebbe essere più utile in Android, in cui non potevo assolutamente utilizzare "RU" locale per DateTime. –

+0

Se si desidera utilizzare Android, ho aggiunto una soluzione per questo argomento. – CoolMind

1

Mentre una risposta accettata di @Meno Hochschild e https://stackoverflow.com/a/27421103/2914140 sono corrette, voglio aggiungere un po '.

È sufficiente impostare Locale("ru"), quindi creare e applicare 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); 
} 

Ma se si desidera personalizzarlo, mostrerò un processo.

Dopo molte eccezioni mi sono reso conto che i giorni della settimana non iniziano da lunedì (vedi 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

Per Java 8 è possibile utilizzare un nuovo modello.

In breve: Il modello "LLLL" otterrà un caso nominativo:

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

Il pattern "MMMM" restituirà un String in genitivo caso:

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

In alternativa, invece di mesi russi hardcoding in serie (dal momento che abbiamo polacco, ucraino e altre lingue), è possibile utilizzare l'enum java.time.Month. Contiene entrambi i mesi il numero int e il nome String.

Problemi correlati