例如:用户的时区为PST,Locale为美国,则期望的格式为“MM/dd/yyyy”,如果用户的时区为IST,Locale为印度,则期望的格式为“dd/MM/yyyy”。
如何获得这个日期格式?
注:我想获取格式而不是实际日期,以便在其他地方使用。
将Locale
翻译为日期/时间格式的逻辑封装在java.text.SimpleDateFormat#SimpleDateFormat
构造函数中,准确地说在sun.util.resources.LocaleData#getDateFormatData
方法中。该方法提供了ResourceBundle
,然后根据所选择的样式查询特定模式。
换句话说 - 不幸的是JDK似乎没有提供API/SPI来访问原始格式。我的建议是始终使用Locale
并将其传递给格式化/解析方法。
你真的需要时区来设置日期格式吗?通常的做法是在本地化属性文件中为某个语言环境(或语言环境_国家)设置日期格式。我认为这已经足够了。
SimpleDateFormat
。具体被 DateTimeFormatter
替换。
您问道:
我有用户的时区和语言环境,现在我想获取日期格式。
实际上没有必要获得特定语言环境下使用的格式模式。
DateTimeFormatter
上的 .ofLocalized…
方法返回一个格式化对象,可以自动本地化表示日期时间对象值的文本。因此,您不需要查看模式,只需请求生成的文本结果即可。
FormatStyle
对象控制文本的长度或缩写形式。Locale
确定在本地化时使用的人类语言和文化规范。
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f =
DateTimeFormatter
.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( locale )
;
String output = zdt.format( f ) ;
将内容输出到控制台。
System.out.println( zdt.toInstant().toString() ) ; // Adjust to UTC.
System.out.println( zdt.toString() ) ; // Generate text in standard ISO 8601 format extended wisely to append the name of the time zone in square brackets.
System.out.println( output ) ; // Automatically formatted content.
在IdeOne.com上实时运行代码。
2020-07-13T23:26:40.554180Z
2020-07-14T08:26:40.554180+09:00[Asia/Tokyo]
2020年7月14日日本标准时间上午8点26分40秒
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧传统日期时间类,如java.util.Date
、Calendar
和SimpleDateFormat
。
要了解更多,请参阅Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
你可以直接使用与JDBC 4.2或更高版本兼容的JDBC驱动程序,直接与数据库交换java.time对象。不需要字符串,也不需要java.sql.*
类。Hibernate 5和JPA 2.2支持java.time。String patternForStyleAndLocale = org.joda.time.format.DateTimeFormat.patternForStyle("S-", locale);
不幸的是,这只提供了两位数的年份。一个解决方法是:
if (!org.apache.commons.lang.StringUtils.contains(patternForStyleAndLocale, "yyyy"))
{
// The default Joda pattern only has a two digit year for US and Europe, China etc - but we want four digit years
patternForStyleAndLocale = StringUtils.replace(patternForStyleAndLocale, "yy", "yyyy");
}
ConcurrentHashMap<Locale, String>
中。"dd MMM yyyy" // UK: "25 Dec 2010" FRANCE: "25 déc. 2010" etc..
然而... 我刚刚从您后来的评论中注意到,您想将模式传递给JavaScript - 这可能会非常困难,因为JS使用不同的模式格式化Java(例如,ISO日期在Java中为"yyyy-MM-dd"
,在JS中为"yy-mm-dd"
)。我尚未尝试解决这个问题,但我可能会在JS或Java中使用一些字符串映射,简单地从Java模式映射到JS。当然,您必须事先了解每种语言可能遇到的每种模式。
听起来你想要在 DateFormat 上使用 静态getInstance
方法。它们接受一个整数常量来表示风格(短格式、长格式等),还可以选择一个不同的 Locale(而不是 JVM 的默认值)。