SimpleDateFormat и строка формата на основе локали
-
12-09-2019 - |
Вопрос
Я пытаюсь отформатировать дату в Java по-разному в зависимости от заданного языкового стандарта.Например, я хочу, чтобы английские пользователи видели «1 ноября 2009 г.» (в формате «МММ д, гггг»), а норвежские пользователи видели «1.ноябрь2009» («ум.М-М-М.уууу»).
Часть месяца работает нормально, если я добавляю локаль в конструктор SimpleDateFormat, но как насчет остального?
Я надеялся, что смогу добавить в SimpleDateFormat строки формата в сочетании с локалями, но не нашел способа сделать это.Возможно ли это, или мне нужно позволить моему коду проверить локаль и добавить соответствующую строку формата?
Решение
Использовать DateFormat.getDateInstance(стиль int, языковой стандарт) вместо того, чтобы создавать свои собственные шаблоны с SimpleDateFormat
.
Другие советы
SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy", Locale.ENGLISH);
String formatted = dateFormat.format(the_date_you_want_here);
Использовать стиль + локаль: DateFormat.getDateInstance(стиль int, языковой стандарт)
Проверять http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html
Запустите следующий пример, чтобы увидеть различия:
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
public class DateFormatDemoSO {
public static void main(String args[]) {
int style = DateFormat.MEDIUM;
//Also try with style = DateFormat.FULL and DateFormat.SHORT
Date date = new Date();
DateFormat df;
df = DateFormat.getDateInstance(style, Locale.UK);
System.out.println("United Kingdom: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.US);
System.out.println("USA: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.FRANCE);
System.out.println("France: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.ITALY);
System.out.println("Italy: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.JAPAN);
System.out.println("Japan: " + df.format(date));
}
}
Выход:
United Kingdom: 25-Sep-2017
USA: Sep 25, 2017
France: 25 sept. 2017
Italy: 25-set-2017
Japan: 2017/09/25
вр; доктор
LocalDate.now().format(
DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM )
.withLocale( new Locale( "no" , "NO" ) )
)
Трудные классы java.util.Date
и SimpleDateFormat
теперь являются устаревшими и заменены классами java.time.
LocalDate
А LocalDate
class представляет значение только даты без времени суток и часового пояса.
Часовой пояс имеет решающее значение при определении даты.В любой момент дата варьируется по всему земному шару в зависимости от зоны.Например, через несколько минут после полуночи в Париж, Франция это новый день, хотя еще «вчера» в Монреаль, Квебек.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
DateTimeFormatter
Использовать DateTimeFormatter
для создания строк, представляющих только часть даты или часть времени.
А DateTimeFormatter
класс может автоматически локализовать.
Для локализации укажите:
FormatStyle
чтобы определить, насколько длинной или сокращенной должна быть строка.Locale
определить (а) человеческий язык для перевода названия дня, названия месяца и т. д. и (б) культурные нормы, решающие вопросы сокращений, использования заглавных букв, пунктуации и т. д.
Пример:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l );
String output = ld.format( f );
Идя в другом направлении, вы можете проанализировать локализованную строку.
LocalDate ld = LocalDate.parse( input , f );
Обратите внимание, что локаль и часовой пояс полностью ортогональны.Вы можете представить момент в Монреале на японском языке или момент в Окленде, Новая Зеландия, на языке хинди.
Другой пример:Изменять 6 junio 2012
(испанский) чтобы 2012-06-06
(стандартный ИСО 8601 формат).Классы java.time по умолчанию используют форматы ISO 8601 для анализа/генерации строк.
String input = "6 junio 2012";
Locale l = new Locale ( "es" , "ES" );
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "d MMMM uuuu" , l );
LocalDate ld = LocalDate.parse ( input , f );
String output = ld.toString(); // 2012-06-06.
Просмотр форматов
Вот пример кода для просмотра результатов нескольких форматов в нескольких языковых стандартах, которые автоматически локализуются.
Ан EnumSet
представляет собой реализацию Set
, оптимизированный как для низкого использования памяти, так и для высокой скорости выполнения при сборе Enum
объекты.Так, EnumSet.allOf( FormatStyle.class )
дает нам коллекцию всех четырех FormatStyle
перечислить объекты для цикла.Для получения дополнительной информации см. Учебник Oracle по типам перечислений.
LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 );
List < Locale > locales = new ArrayList <>( 3 );
locales.add( Locale.CANADA_FRENCH );
locales.add( new Locale( "no" , "NO" ) );
locales.add( Locale.US );
// Or use all locales (almost 800 of them, for about 120K text results).
// Locale[] locales = Locale.getAvailableLocales(); // All known locales. Almost 800 of them.
for ( Locale locale : locales )
{
System.out.println( "------| LOCALE: " + locale + " — " + locale.getDisplayName() + " |----------------------------------" + System.lineSeparator() );
for ( FormatStyle style : EnumSet.allOf( FormatStyle.class ) )
{
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale );
String output = ld.format( f );
System.out.println( output );
}
System.out.println( "" );
}
System.out.println( "« fin »" + System.lineSeparator() );
Выход.
------| LOCALE: fr_CA — French (Canada) |----------------------------------
mardi 23 janvier 2018
23 janvier 2018
23 janv. 2018
18-01-23
------| LOCALE: no_NO — Norwegian (Norway) |----------------------------------
tirsdag 23. januar 2018
23. januar 2018
23. jan. 2018
23.01.2018
------| LOCALE: en_US — English (United States) |----------------------------------
Tuesday, January 23, 2018
January 23, 2018
Jan 23, 2018
1/23/18
« fin »
О java.time
А java.time Framework встроен в Java 8 и более поздних версий.Эти занятия заменяют надоедливые старые наследие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
А Джода-Время проект, сейчас в Режим обслуживания, советует перейти на java.time занятия.
Чтобы узнать больше, см. Учебное пособие по Oracle.И найдите Stack Overflow для множества примеров и объяснений.Спецификация ДжСР 310.
Вы можете обменять java.time объекты непосредственно с вашей базой данных.Использовать JDBC-драйвер совместимый с JDBC 4.2 или позже.Нет необходимости в веревках, нет необходимости в java.sql.*
занятия.
Где получить классы java.time?
- Ява ЮВ 8, Ява ЮВ 9, и позже
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- В Java 9 добавлены некоторые незначительные функции и исправления.
- Ява ЮВ 6 и Ява ЮВ 7
- Большая часть функций java.time перенесена на Java 6 и 7 в ТриДесять-Бэкпорт.
- Андроид
- Более поздние версии реализации пакетов Android классов java.time.
- Для более ранних версий Android ТриTenABP проект адаптируется ТриДесять-Бэкпорт (упомянутое выше).Видеть Как использовать ThreeTenABP….
А ТриДесять-Экстра проект расширяет java.time дополнительными классами.Этот проект является испытательным полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
, и более.
Локализация строки даты:
Судя по сообщению Redsonic:
private String localizeDate(String inputdate, Locale locale) {
Date date = new Date();
SimpleDateFormat dateFormatCN = new SimpleDateFormat("dd-MMM-yyyy", locale);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
try {
date = dateFormat.parse(inputdate);
} catch (ParseException e) {
log.warn("Input date was not correct. Can not localize it.");
return inputdate;
}
return dateFormatCN.format(date);
}
String localizedDate = localizeDate("05-Sep-2013", new Locale("zh","CN"));
будет как 05 февраля 2013 г.
Это отобразит дату в соответствии с пользователем текущий язык:
Чтобы вернуть дату и время:
import java.text.DateFormat;
import java.util.Date;
Date date = new Date();
DateFormat df = DateFormat.getDateTimeInstance();
String myDate = df.format(date);
31 декабря 1969 г., 19:00:02
Только для даты возврата используйте:
DateFormat.getDateInstance()
31 декабря 1969 г.
String text = new SimpleDateFormat("E, MMM d, yyyy").format(date);
Стиль Java 8 для заданной даты
LocalDate today = LocalDate.of(1982, Month.AUGUST, 31);
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRENCH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.JAPANESE)));
Java8
import java.time.format.DateTimeFormatter;
myDate.format(DateTimeFormatter.ofPattern("dd-MMM-YYYY",new Locale("ar")))