如何将Calendar.getInstance与指定的区域设置一起使用



我正在尝试将Calendar.getInstance(Locale l)与指定的Locale一起使用,但无法工作。我想不出我做错了什么。

Java文档。比如:

getInstancepublic static Calendar getInstance(Locale aLocale)使用默认时区和指定的区域设置获取日历返回的日历基于给定区域设置的默认时区中的当前时间参数:aLocale-周数据的区域设置退货:a日历。

我的代码:

public static void main (String[] args){
Locale local = new Locale("pt", "BR");
Calendar c = Calendar.getInstance(local); // here I am using the method
System.out.println(c.getTime()); // and here, I cannot figure out why is not working

DateFormat dt = DateFormat.getDateInstance(DateFormat.LONG, local);
String s = dt.format(c.getTime());
System.out.println(s); // here just a example in portuguese Brasil
}

输出:

4月29日星期三10:18:16 BRT 2015

2015年4月29日

第一个print必须在Locale("pt", "BR")中吗?

Loc的Answer是正确的:对Calendar::getTime的调用会生成一个java.util.Date对象。java.util.Date类没有显式时区,但它的toString方法在生成String时混淆地应用了JVM的当前默认时区。

所有非常令人困惑的名称和行为-许多的一些原因是为了避免这些设计糟糕、令人困惑和麻烦的旧遗留日期-时间类。相反,您应该使用正式取代旧类的java.time类。

java.time

获取UTC中的当前时刻。Instant类表示以UTC为单位的时间线上的一个时刻,分辨率为纳秒(最多九(9)位小数)。

Instant instant = Instant.now();

您可以通过调用toString创建一个字符串,以标准ISO 8601格式表示该值。

String output = instant.toString();

2016-09-28T19:38:21Z

问题中的代码忽略了时区问题。当您没有指定时区时,JVM的当前默认时区将隐式应用。最好明确指定。

请注意,Locale和时区是两个完全不同的问题

  • Locale,以确定(a)用于翻译日名、月名等的人类语言,以及(b)决定缩写、大写、标点符号等问题的文化规范
  • 时区确定用于显示日期时间值的挂钟时间

您可以将两者任意组合。例如,带有法语区域设置的印度加尔各答时区,或带有新西兰奥克兰时区的巴西-葡萄牙区域设置。

Locale locale = new Locale("pt", "BR");
ZoneId z = ZoneId.of( "Pacific/Auckland" );

将时区应用为ZoneId以生成ZonedDateTime。从概念上讲,可以将其视为ZonedDateTime = ( Instant + ZoneID )

continent/region的格式指定一个适当的时区名称。千万不要使用3-4个字母的缩写,如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZonedDateTime zdt = instant.atZone( z );

Locale不影响表达的意义。我们可以让Locale对象在通过DateTimeFormatter类生成表示日期-时间值的字符串时驱动的自动本地化。指定FormatStyle以确定字符串的长度或缩写。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( locale );
String output = zdt.format( f );

转储到控制台。这里看到的instantzdt对象表示时间线上的同一时刻、同一点。唯一的区别是通过不同地区的挂钟时间来观察。

System.out.println ( "instant.toString(): " + instant 
+ " | zdt: " + zdt 
+ " | output: " + output );

instant.toString():2016-09-28T20:38.242Z|zdt:2016-09-29T09:20:38.242+13:00[太平洋/奥克兰]|输出:Quinta feira,2016年9月29日09h20min38s NZDT

转换

避免使用旧的.Date.Calendar类。但是,如果必须将它们与尚未针对java.time类型更新的旧代码一起使用,则可以进行转换。使用添加到旧类中的新方法。这里我们称之为java.util.GregorianCalendar.from( ZonedDateTime )

java.util.Calendar cal = java.util.GregorianCalendar.from( zdt ) ;

而且,走向另一个方向:

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;

关于java.time

java.time框架是在java 8及更高版本中构建的。这些类取代了诸如java.util.Date.Calendar、&CCD_ 30。

JodaTime项目现在处于维护模式,建议迁移到java.Time.

要了解更多信息,请参阅Oracle教程。并在Stack Overflow中搜索许多示例和解释。

大部分java.time功能都是向后移植到Java6&ThreeTen Backport中的7,并在ThreeTenABP中进一步适用于Android(请参阅如何使用…)。

ThreeTen Extra项目用额外的类扩展了java.time。这个项目是将来可能添加到java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等等。

您的第一次打印只是打印日期信息&此打印使用默认语言环境的Java(英文)

System.out.println(c.getTime());

此打印将执行:c.getTime().toString()方法,此方法使用默认语言环境(英语)-您可以查看Date.toString()源代码,以查看使用默认语言区域的Java。

这就是为什么输出为"2015年4月29日星期三10:18:16 BRT">

如果要打印输出,请使用葡萄牙语。你必须选择二次打印。

最新更新