windows 如何在尊重用户操作系统设置的 Java 中设置日期和时间格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6711925/
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
How can I set date and time formatting in Java that respects the user's OS settings
提问by Ian Leslie
I am running my Java app on a Windows 7 machine where my regional settings are set up to format dates as YYYY-mm-dd and time as HH:mm:ss (e.g. "2011-06-20 07:50:28"). But when I use DateFormat.getDateTimeInstance().format
to format my date I do not see that instead I get "20-Jun-2011 7:50:28 AM". What do I need to do to format dates in the way that my customers have their OS setup to display dates?
我在 Windows 7 机器上运行我的 Java 应用程序,我的区域设置设置为日期格式为 YYYY-mm-dd,时间格式为 HH:mm:ss(例如“2011-06-20 07:50:28”) . 但是当我DateFormat.getDateTimeInstance().format
用来格式化我的日期时,我没有看到,而是得到“20-Jun-2011 7:50:28 AM”。我需要怎么做才能按照我的客户将其操作系统设置为显示日期的方式来格式化日期?
Here is what my code in question looks like:
这是我有问题的代码的样子:
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));
}
The Messages.getFormattedString
calls are using MessageFormat
to put the date into a sentence that will look like this:
该Messages.getFormattedString
呼叫使用MessageFormat
把日期成句,这将是这样的:
Play the turn 'QB Nat vs Ian 008' (received 20-Jun-2011 7:50:28 AM)
玩转“QB Nat vs Ian 008”(收到 20-Jun-2011 7:50:28 AM)
However my OS settings are setup to format the date as I described above and I expected to see this:
但是,我的操作系统设置已设置为如上所述格式化日期,我希望看到以下内容:
Play the turn 'QB Nat vs Ian 008' (received 2011-06-20 07:50:28)
玩转'QB Nat vs Ian 008'(收到 2011-06-20 07:50:28)
I searched here and other Java programming sites and could not find the answer but this seems like such an obvious thing to want to do that I feel like I am missing something obvious.
我在这里和其他 Java 编程站点进行了搜索,但找不到答案,但这似乎是一件很明显的事情,我觉得我错过了一些明显的东西。
采纳答案by Bringer128
You can't do this in pure Java. There is no way Sun/Oracle could make this system independent.
你不能在纯 Java 中做到这一点。Sun/Oracle 无法使该系统独立。
A quick browse of the .NET libraries gives this page- to quote:
.NET 库的快速浏览提供了这个页面- 引用:
The user might choose to override some of the values associated with the current culture of Windows through the regional and language options portion of Control Panel. For example, the user might choose to display the date in a different format or to use a currency other than the default for the culture. If the CultureInfo.UseUserOverride property is set to true, the properties of the CultureInfo.DateTimeFormat object, the CultureInfo.NumberFormat object, and the CultureInfo.TextInfo object are also retrieved from the user settings.
用户可以选择通过控制面板的区域和语言选项部分覆盖与当前 Windows 文化相关的某些值。例如,用户可能选择以不同的格式显示日期或使用不同于文化默认值的货币。如果 CultureInfo.UseUserOverride 属性设置为 true,则还会从用户设置中检索 CultureInfo.DateTimeFormat 对象、CultureInfo.NumberFormat 对象和 CultureInfo.TextInfo 对象的属性。
I would suggest that you do this in a way that is system dependent upon Windows if you need this functionality (e.g. access the Windows registry as @laz suggested).
如果您需要此功能(例如,按照@laz 的建议访问 Windows 注册表),我建议您以系统依赖于 Windows 的方式执行此操作。
回答by Frankie
First you have to tell Java what your system LOCALE looks like.
首先,您必须告诉 Java 您的系统 LOCALE 是什么样的。
Check Java System.String locale = System.getProperty("user.language")
检查 Java 系统。String locale = System.getProperty("user.language")
And then format the date accordinly (SimpleDateFormat)SimpleDateFormat(String pattern, Locale locale)
然后相应地格式化日期(SimpleDateFormat)SimpleDateFormat(String pattern, Locale locale)
Refer to the practical Java code for a working example...
有关工作示例,请参阅实用的 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
回答by Allon Guralnek
I found this Java utility class by JetBrains that retrieves all the custom locale settings from the OS (both from Windows and Mac) and does the correct formatting for you:
我发现 JetBrains 的这个 Java 实用程序类可以从操作系统(Windows 和 Mac)中检索所有自定义语言环境设置,并为您执行正确的格式设置:
It's under the Apache 2.0 license so you can probably use it in your project.
它在 Apache 2.0 许可下,所以你可以在你的项目中使用它。
回答by zakgof
Oracle JDK 8 fully supports formatting using user-customized OS regional settings.
Oracle JDK 8 完全支持使用用户自定义的操作系统区域设置进行格式化。
Just set system property java.locale.providers=HOST
只需设置系统属性 java.locale.providers=HOST
According to https://docs.oracle.com/javase/8/docs/technotes/guides/intl/enhancements.8.html:
根据https://docs.oracle.com/javase/8/docs/technotes/guides/intl/enhancements.8.html:
HOST represents the current user's customization of the underlying operating system's settings. It works only with the user's default locale, and the customizable settings may vary depending on the OS, but primarily Date, Time, Number, and Currency formats are supported.
HOST 代表当前用户对底层操作系统设置的自定义。它仅适用于用户的默认区域设置,可自定义的设置可能因操作系统而异,但主要支持日期、时间、数字和货币格式。
The actual implementation of this formatter is available in the class sun.util.locale.provider.HostLocaleProviderAdapterImpl
.
If using system property is not acceptable (say, your don't want to affect the whole application), it's possible to use that provider class directly. The class is internal API, but can be reached using reflection:
这个格式化程序的实际实现在类中可用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;
}
回答by laz
I looks like you will need to access the Windows registry for this. See this question for various solutions to that read/write to Windows Registry using Java.
我看起来您需要为此访问 Windows 注册表。有关使用 Java 读取/写入 Windows 注册表的各种解决方案,请参阅此问题。
Once you choose one of the many methods of accessing the registry you will need to get the correct key from the registry for the format. Thisdocument indicates the key to use is HKEY_USERS\.Default\Control Panel\International
.
一旦您选择了访问注册表的多种方法之一,您将需要从注册表中获取正确的密钥格式。本文档指出使用的密钥是HKEY_USERS\.Default\Control Panel\International
。
When using GNOME in Linux, you can use the gconftool
command similar to the reg
command for Windows as mentioned in the prior links about the Windows registry. I see the key /apps/panel/applets/clock_screen0/prefs/custom_format
in my configuration, though it is blank since I am using the default:
在 Linux 中使用 GNOME 时,您可以使用gconftool
类似于reg
前面关于 Windows 注册表的链接中提到的 Windows 命令的命令。我/apps/panel/applets/clock_screen0/prefs/custom_format
在我的配置中看到了密钥,尽管它是空白的,因为我使用的是默认值:
gconftool -g /apps/panel/applets/clock_screen0/prefs/custom_format
I'm not sure if that is the value you'd want to use for your purposes or not.
我不确定这是否是您想要用于您的目的的价值。
On Mac OS, I'm not sure what you would do.
在 Mac OS 上,我不确定您会做什么。
回答by Mech Software
Perhaps I'm misunderstanding what you're getting at here but you need to use the Locale.
也许我误解了你在这里得到的东西,但你需要使用语言环境。
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
By using Locale you can control what format for what region you're using.
通过使用区域设置,您可以控制您使用的区域的格式。
回答by Ole V.V.
java -Djava.locale.providers=HOST,CLDR,COMPAT YourProgram
Date and time formats are part of Java's locale data. Java can get its locale data from up to four sources. Which ones it uses is controlled by the java.locale.providers
system property. Default up to Java 8 was JRE,SPI
. From Java 9 it's CLDR,COMPAT
. None of these will get you the date and time data from the operating system, but you can get them by supplying the HOST
locale provider, for example as in the command line above. When running your program with this property definition, you may for example have:
日期和时间格式是 Java 语言环境数据的一部分。Java 最多可以从四个来源获取其语言环境数据。它使用哪些由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);
This will print the current date and time in the format defined by the underlying operating system. To the extend that the operating system supports it you can vary the length of the output by using format styles FULL
, LONG
, MEDIUM
and SHORT
.
这将以底层操作系统定义的格式打印当前日期和时间。向延伸,该操作系统支持它可以通过使用格式样式改变输出的长度FULL
,LONG
,MEDIUM
和SHORT
。
For most purposes you will want to have a DateTimeFormatter
knowing the format as in the above code. In the rare case where you want to know a format pattern string that is possible too:
对于大多数用途,您需要DateTimeFormatter
了解上述代码中的格式。在极少数情况下,您也想知道可能的格式模式字符串:
String osFormat = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.getDefault());
The first argument to getLocalizedDateTimePattern
is the dateformat style. The second is the timestyle.
第一个参数getLocalizedDateTimePattern
是日期格式样式。二是时间风格。