我有一个时区和用户的Locale。现在我想得到日期模式。
例如:用户的时区PST和Locale US以及我期望的模式是“MM / dd / yyyy”,如果用户的时区是IST和Locale India,那么我期望的模式是“dd / MM / yyyy”
如何获得这个?
注意:我想让模式不是实际日期,以便我可以在其他地方使用它。
答案 0 :(得分:3)
将Locale
转换为日期/时间格式的逻辑隐藏在java.text.SimpleDateFormat#SimpleDateFormat
构造函数中,正好在sun.util.resources.LocaleData#getDateFormatData
中。此方法提供ResourceBundle
,然后根据选择的样式查询特定模式。
换句话说 - 遗憾的是JDK似乎没有提供API / SPI来访问原始格式。我的建议是一直使用Locale
并将其传递给格式化/解析方法。
答案 1 :(得分:1)
你真的需要TZ的日期模式吗?通常的方法是在区域设置(或locale_country)的本地化属性文件中使用数据模式。我认为这已经足够了。
答案 2 :(得分:1)
现代的解决方案使用了几年前的 java.time 类,该类取代了可怕的旧类,例如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.
请参阅此code run live at IdeOne.com。
2020-07-13T23:26:40.554180Z
2020-07-14T08:26:40.554180 + 09:00 [亚洲/东京]
Mardi 14 Julillet 2020à08 h 26 min 40 s heure normale du Japon
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
要了解更多信息,请参阅Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规范为JSR 310。
Joda-Time项目(现在位于maintenance mode中)建议迁移到java.time类。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。 Hibernate 5和JPA 2.2支持 java.time 。
在哪里获取java.time类?
答案 3 :(得分:0)
听起来你想在DateFormat上使用static getInstance
methods。它们为样式(短,长等)和可选的不同Locale(而不是JVM的默认值)采用整数常量。
答案 4 :(得分:0)
您可以使用Interface Map
k将是Locale v将是一个带有日期模式的字符串
答案 5 :(得分:0)
如果您正在使用Joda Time(如果您有任何选择,为什么不能?它几乎被捆绑到JDK 1.7中)您可以这样做:
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。当然,您必须知道每种语言可能遇到的每种模式。