我有这个奇怪的问题,当我创建一个带有语言环境的日历时,TimeZone只是恢复到本地日历
public void start(Locale locale){
String s = locale.getDisplayName();
System.err.println(s);
Calendar c = new GregorianCalendar(locale);
System.err.println(c.getTimeZone());
}
这是输出:
español (Argentina)
sun.util.calendar.ZoneInfo[id="Europe/Bucharest", //etc more useless date here....
如何从特定区域设置获得适当的时间?
答案 0 :(得分:37)
简短的回答:你不能。
答案很长:没有“适合当地的时区”这样的事情。这只是因为有少数国家拥有多个时区(例如美国)。时区是一个不同的概念。
无论如何,您正在寻找解决问题的方法。我猜你正在编写一个Web应用程序,你发现时区正在恢复到服务器默认值。这是典型的情况。 Locale.getDefault()
和TimeZone.getDefault()
都将返回与服务器相关的信息。 JVM无法知道“正确”的时区。那么你能做些什么呢?
DateFormat
实例,它将自动转换时区。在这三种可能的选择中,我总是选择数字1.通过将时区信息添加到用户个人资料中,您可以确定他/她的首选时区是什么,无论他们当前的网络浏览器等等。请保持请记住,有些用户可能希望在访问其他国家时使用您的应用程序......
答案 1 :(得分:1)
Locale
Locale
代表一对:
Locale
(不是地理)。尽管Locale
可以使用国家或地区作为代表文化规范的方式,但这并不意味着用户在特定的地理区域内。例如,魁北克的一位工程师在日本东京的一次会议上将使用Locale.CANADA_FRENCH
的语言环境,但在旅行期间她的时区可能是Asia/Tokyo
。
ZoneId
time zone,ZoneId
代表特定地区人民使用的offset-from-UTC的过去,现在和将来的历史。偏移量仅是UTC使用的本初子午线之前或之后数小时-数分钟-秒。世界各地的政界人士都表现出对重新定义时区并更改其辖区使用的偏移量的兴趣。实际上,那些采用“夏令时”(DST)愚蠢做法的地区每年都会偏移两次,大约六个月一次。
➥因此,不,您不能仅从给定的语言环境获得当前时间或时区。
当我创建一个具有区域设置的日历时,TimeZone会还原为本地区域
您使用的是可怕的日期时间类,而现在这些类是由JSR 310定义的现代 java.time 类所取代的。
要获取当前的UTC时间(零时分秒),请使用Instant
。根据定义,Instant
始终使用UTC。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
如果要在特定时区中使用当前时刻,请指定ZoneId
以获取ZonedDateTime
对象。
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen in the wall-clock time used by the people of a particular region.
至于知道要应用的时区,正如我上面所说,您必须:
ZoneId.systemDefault
),或…您可以通过致电ZoneId.getAvailableZoneIds
获取已知时区的列表。
Calendar c = new GregorianCalendar( locale ) ;
您可能对此GregorianCalendar
的构造方法感到困惑,但认为它是Locale
。
此构造函数是在遗留日期时间类中发现的很多错误的设计决策之一。直白地说,这些遗留类非常糟糕,由不了解日期时间处理的复杂性和微妙性的人设计。 Sun, Oracle, and the JCP community decided有充分理由将其替换为 java.time 。
Locale
在生成表示日期时间对象的值以显示给用户的文本时与时区相交。 Locale
指定用于翻译月份名称,星期几名称等的语言。 Locale
规定了用于决定问题的文化规范,例如缩写月份或星期几(名称是否大写?是否加了“ FULL STOP”?),订购日期,月份和年份以及其他此类方面。