Как настроить форматирование даты и времени в Java, который соответствует настройкам пользовательской ОС
Я запускаю свое Java-приложение на компьютере под управлением Windows 7, где мои региональные настройки настроены на форматирование дат как YYYY-mm-dd и время как HH: mm: ss (например, "2011-06-20 07:50: 28" ). Но когда я использую DateFormat.getDateTimeInstance().format
для форматирования своей даты, я не вижу, что вместо этого получаю "20 июня 2011 года 7:50:28". Что мне нужно сделать, чтобы отформатировать даты так, чтобы мои клиенты установили настройки своей ОС для отображения дат?
Вот как выглядит мой код:
File selGameLastTurnFile = selectedGame.getLastTurn ().getTurnFile ();
Date selGameModifiedDate = new Date (selGameLastTurnFile.lastModified());
if (selectedGame.isYourTurn ()) {
gameInfo = Messages.getFormattedString ("WhoseTurnIsIt.Prompt.PlayTurn", //$NON-NLS-1$
FileHelper.getFileName (selGameLastTurnFile),
DateFormat.getDateTimeInstance().format(selGameModifiedDate));
} else {
gameInfo = Messages.getFormattedString ("WhoseTurnIsIt.Prompt.SentTurn", //$NON-NLS-1$
selGameLastTurnFile.getName (),
DateFormat.getDateTimeInstance().format(selGameModifiedDate));
}
В вызовах Messages.getFormattedString
используется MessageFormat
, чтобы поместить дату в предложение, которое будет выглядеть следующим образом:
Слушайте ход "QB Nat vs Ian 008" (получен 20 июня 2011 года 7:50:28)
Однако настройки моей ОС настроены на форматирование даты, как я описал выше, и я ожидал увидеть это:
Сыграйте в ход "QB Nat vs Ian 008" (получен 2011-06-20 07:50:28)
Я искал здесь и других сайтов программирования Java и не мог найти ответ, но это похоже на такую очевидную вещь, которая хочет сделать это, я чувствую, что мне не хватает чего-то очевидного.
Ответы
Ответ 1
Вы не можете сделать это в чистой Java. Sun/Oracle не может сделать эту систему независимой.
Быстрый просмотр библиотек .NET дает эту страницу - цитата:
Пользователь может выбрать переопределение некоторых значений, связанных с текущей культурой Windows, с помощью региональных и языковых параметров панели управления. Например, пользователь может выбрать отображение даты в другом формате или использование валюты, отличной от значения по умолчанию для культуры. Если для свойства CultureInfo.UseUserOverride установлено значение true, свойства объекта CultureInfo.DateTimeFormat, объект CultureInfo.NumberFormat и объект CultureInfo.TextInfo также извлекаются из пользовательских настроек.
Я бы предположил, что вы делаете это так, чтобы система зависела от Windows, если вам нужна эта функциональность (например, для доступа к реестру Windows в качестве предложенного @laz).
Ответ 2
Сначала вы должны сказать Java, как выглядит ваша система LOCALE.
Проверить систему Java.
String locale = System.getProperty("user.language")
А затем отформатируйте дату (SimpleDateFormat)
SimpleDateFormat(String pattern, Locale locale)
Обратитесь к практическому Java-коду для рабочего примера...
String systemLocale = System.getProperty("user.language");
String s;
Locale locale;
locale = new Locale(systemLocale );
s = DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(new Date());
System.out.println(s);
// system locale is PT outputs 16/Jul/2011
locale = new Locale("us");
s = DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(new Date());
System.out.println(s);
// outputs Jul 16, 2011
locale = new Locale("fr");
s = DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(new Date());
System.out.println(s);
// outputs 16 juil. 2011
Ответ 3
Я нашел этот класс утилиты Java JetBrains, который извлекает все пользовательские настройки локали из ОС (как из Windows, так и из Mac) и делает правильное форматирование для вас:
https://github.com/JetBrains/intellij-community/blob/master/platform/util/src/com/intellij/util/text/DateFormatUtil.java
Он под лицензией Apache 2.0, поэтому вы можете использовать его в своем проекте.
Ответ 4
Похоже, вам понадобится доступ к реестру Windows для этого. См. Этот вопрос для различных решений для чтения/записи в реестр Windows с использованием Java.
Как только вы выберете один из многих способов доступа к реестру, вам нужно будет получить правильный ключ из реестра для формата. В этом документе указывается, что ключ используется HKEY_USERS\.Default\Control Panel\International
.
При использовании GNOME в Linux вы можете использовать команду gconftool
, аналогичную команде reg
для Windows, как указано в предыдущих ссылках о реестре Windows. Я вижу ключ /apps/panel/applets/clock_screen0/prefs/custom_format
в моей конфигурации, хотя он пуст, так как я использую значение по умолчанию:
gconftool -g /apps/panel/applets/clock_screen0/prefs/custom_format
Я не уверен, что это значение, которое вы хотите использовать для своих целей или нет.
В Mac OS я не уверен, что вы будете делать.
Ответ 5
Oracle JDK 8 полностью поддерживает форматирование с использованием пользовательских региональных настроек ОС.
Просто установите системное свойство java.locale.providers=HOST
Согласно https://docs.oracle.com/javase/8/docs/technotes/guides/intl/enhancements.8.html:
HOST представляет текущую пользовательскую настройку базовых настроек операционной системы. Он работает только с пользовательским языком по умолчанию, а настраиваемые параметры могут различаться в зависимости от ОС, но в основном поддерживаются форматы Дата, Время, Число и Валюта.
Фактическая реализация этого форматера доступна в классе sun.util.locale.provider.HostLocaleProviderAdapterImpl
. Если использование системного свойства недопустимо (скажем, вы не хотите влиять на все приложение), можно напрямую использовать этот класс провайдера. Класс является внутренним API, но может быть достигнут с помощью отражения:
private static DateFormat getSystemDateFormat() throws ReflectiveOperationException {
Class<?> clazz = Class.forName("sun.util.locale.provider.HostLocaleProviderAdapterImpl");
Method method = clazz.getMethod("getDateFormatProvider");
DateFormatProvider dateFormatProvider = (DateFormatProvider)method.invoke(null);
DateFormat dateFormat = dateFormatProvider.getDateInstance(DateFormat.MEDIUM, Locale.getDefault(Locale.Category.FORMAT));
return dateFormat;
}
Ответ 6
Возможно, я не понимаю, что вы здесь делаете, но вам нужно использовать Locale.
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
Используя Locale, вы можете управлять форматом для того региона, в котором вы используете.
Ответ 7
java -Djava.locale.providers=HOST,CLDR,COMPAT YourProgram
Форматы даты и времени являются частью данных локали Javas. Java может получать данные о локали из четырех источников. Какие из них он использует, java.locale.providers
системным свойством java.locale.providers
. По умолчанию до Java 8 был JRE,SPI
. С Java 9 его CLDR,COMPAT
. Ни один из них не даст вам данные о дате и времени из операционной системы, но вы можете получить их, предоставив поставщика локали HOST
, например, как в командной строке выше. При запуске вашей программы с этим определением свойства вы можете, например, иметь:
DateTimeFormatter systemFormatter
= DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Africa/Bangui"));
String formattedDateTime = now.format(systemFormatter);
System.out.println(formattedDateTime);
Это напечатает текущую дату и время в формате, определенном базовой операционной системой. Если операционная система поддерживает его, вы можете изменять длину вывода, используя стили форматирования FULL
, LONG
, MEDIUM
и SHORT
.
Для большинства целей вам понадобится DateTimeFormatter
знающий формат, как в приведенном выше коде. В редком случае, когда вы хотите узнать строку шаблона формата, это также возможно:
String osFormat = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.getDefault());
Первый аргумент getLocalizedDateTimePattern
- это стиль формата даты. Второй стиль времени.