Java';s MessageFormat未将葡萄牙语月份本地化为小写日期
月份名称以大写字母开头,而不是小写 我在本地计算机上运行的一些示例代码:Java';s MessageFormat未将葡萄牙语月份本地化为小写日期,java,date,localization,messageformat,Java,Date,Localization,Messageformat,月份名称以大写字母开头,而不是小写 我在本地计算机上运行的一些示例代码: Locale portugal = new Locale("pt"); Locale brazil = new Locale("pt", "BR"); Locale france = new Locale("fr", "FR"); Object[] params = new Object[] { new Date() }; String pattern = "Today is {0,date,long
Locale portugal = new Locale("pt");
Locale brazil = new Locale("pt", "BR");
Locale france = new Locale("fr", "FR");
Object[] params = new Object[] { new Date() };
String pattern = "Today is {0,date,long}!";
MessageFormat ptFormat = new MessageFormat(pattern, portugal);
MessageFormat brFormat = new MessageFormat(pattern, brazil);
MessageFormat frFormat = new MessageFormat(pattern, france);
StringBuffer ptResult = ptFormat.format(params, new StringBuffer(), new FieldPosition(0));
StringBuffer brResult = brFormat.format(params, new StringBuffer(), new FieldPosition(0));
StringBuffer frResult = frFormat.format(params, new StringBuffer(), null);
System.out.println("Portugal result: " + ptResult.toString());
System.out.println("Brazil result: " + brResult.toString());
System.out.println("France result: " + frResult.toString());
这就是我得到的:
Portugal result: Today is 10 de Julho de 2018!
Brazil result: Today is 10 de Julho de 2018!
France result: Today is 10 juillet 2018!
因此,法语是正确的,但出于某种原因,这两个葡萄牙语变体并非如此
更奇怪的是,我试着添加与一个完全相同的代码,但它根本无法本地化
我在这里误解了什么?tl;博士
- 不同的Java实现在本地化规则上可能有所不同
- Java实现的不同版本在本地化规则上可能有所不同
Month.JULY.getDisplayName( TextStyle.FULL , new Locale( "pt" ) )
在Java8、OracleJDK中,默认情况下使用其自己的本地化规则,我们得到初始cap
朱略
在Java10、OracleJDK中,默认情况下,使用Unicode CLDR规则,我们得到小写
朱略
在Java10中,Oracle JDK在设置VM选项-Djava.locale.providers=COMPAT,SPI
以恢复旧式行为而不是使用Unicode CLDR后,我们得到了初始cap
朱略
细节
- 文化规范定义的格式规则可能因实施和版本而异
- IdeOne.com中的拒绝本地化。只有我们英语李>
- 您使用了错误的类使用java.time处理所有日期时间
产量July
Julho
收益率七月初
不在julho
2018年7月12日2018年7月12日
Month.JULY.getDisplayName(
TextStyle.FULL ,
new Locale( "pt" )
)
朱略
朱略
所以,在使用Java10时,上下文似乎不是问题
java.time
您使用的是现在被java.time类取代的麻烦的旧类
使用java.time.Instant
而不是java.util.Date
。两者都代表UTC中的一个时刻。现代的Instant
类使用更精细的纳秒分辨率,而不是毫秒分辨率
Instant instant = Instant.now() ; // Capture the current moment in UTC.
instant.toString():2018-07-11T05:57:36.446917Z
从UTC调整到该地区的人们使用您想要的特定挂钟时间的时区。应用ZoneId
以获取zoneDateTime
对象。时区与区域设置完全正交。一个与当前内容相关,另一个只影响生成表示该内容的字符串时使用的本地化。例如,您可以使用带有葡萄牙语地区的日本时区
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
现在,我们要生成表示那个时刻的字符串。首先,生成一个标准格式的字符串
,通过在方括号中添加时区名称进行扩展
String output = zdt.toString() ; // Generate ISO 8601 format string.
2018-07-11T17:57:36.446917+12:00[太平洋/奥克兰]
您希望本地化生成的字符串对象。用于控制要生成的字符串的格式。指定用于控制长度或缩写的长度
Locale l_pt = new Locale( "pt" ) ;
Locale l_ptBR = new Locale( "pt" , "BR" ) ;
Locale l_FR = Locale.FRANCE ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ) ;
String output_pt = zdt.format( f.withLocale( l_pt ) ) ;
String output_ptBR = zdt.format( f.withLocale( l_ptBR ) ) ;
String output_FR = zdt.format( f.withLocale( l_FR ) ) ;
夸塔·费拉,2018年7月11日17:57:36新泽兰迪亚河畔
夸塔·费拉,2018年7月11日17:57:36新泽兰迪亚河畔
mercredi 11 juillet 2018年11月17日:57:36《新英格兰的常态》
为了好玩,让我们尝试一下,而不是FULL
2018年7月11日17:57:36 NZST
2018年7月11日17:57:36 NZST
11 juillet 2018á17:57:36 NZSTe
IdeOne拒绝本地化
我喜欢使用IdeOne.com演示Java代码。不幸的是,它的JVM拒绝使用除美国英语以外的任何语言环境。所以,不要使用上面的代码
关于java.time
该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&
该项目现已启动,建议迁移到类
要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是
您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要java.sql.*
类
从哪里获得java.time类
- 然后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
<
String output = zdt.toString() ; // Generate ISO 8601 format string.
Locale l_pt = new Locale( "pt" ) ;
Locale l_ptBR = new Locale( "pt" , "BR" ) ;
Locale l_FR = Locale.FRANCE ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ) ;
String output_pt = zdt.format( f.withLocale( l_pt ) ) ;
String output_ptBR = zdt.format( f.withLocale( l_ptBR ) ) ;
String output_FR = zdt.format( f.withLocale( l_FR ) ) ;