语言环境和时区是正交问题
Locale
ALocale
代表一对:
- 一种人类语言,例如法语、英语或汉语。
- 一组文化规范,用于决定诸如大小写、缩写等格式问题、日期中的日-月-年等元素的顺序以及使用逗号与句号作为小数分隔符等问题。
Locale
不是地域的。虽然Locale
可以使用国家或地区作为代表文化规范的一种方式,但这并不意味着用户在特定的地理区域。例如,一位来自魁北克的工程师在日本东京的一次会议上将使用语言环境,Locale.CANADA_FRENCH
但她的时区可能是Asia/Tokyo
她旅行期间的时间。
ZoneId
时区ZoneId
表示过去、现在和未来对特定地区人民使用的UTC 偏移量变化的历史。偏移量只是 UTC 使用的本初子午线之前或之后的几个小时-分钟-秒。世界各地的政治家都表现出经常重新定义他们的时区和改变他们的管辖区使用的偏移量的倾向。事实上,那些采用愚蠢的夏令时 (DST) 的地区每年都会改变他们的偏移量两次,大约每六个月一次。
➥ 所以,不,你不能从给定的语言环境中获得当前时间或时区。
当我创建带有语言环境的日历时,时区只是恢复为本地日历
您正在使用现在遗留的糟糕的日期时间类,被JSR 310 定义的现代java.time类所取代。
要获取 UTC 中的当前时刻(零时分秒的偏移量),请使用Instant
. 根据定义, AnInstant
始终采用 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.getAvailableZoneIds
。
Calendar c = new GregorianCalendar( locale ) ;
GregorianCalendar
你可能会被这个使用a 的构造函数弄糊涂,这是可以Locale
理解的。
此构造函数是遗留日期时间类中发现的许多糟糕且不正确的设计决策之一。坦率地说,这些遗留类非常糟糕,是由不了解日期时间处理的复杂性和微妙性的人设计的。Sun、Oracle 和 JCP 社区决定用java.time取代它们是有充分理由的。
Locale
在生成表示显示给用户的日期时间对象值的文本时,与时区相交。ALocale
指定用于翻译月份名称、星期几名称等的人类语言。并Locale
规定了决定诸如缩写月份或星期几(名称是否大写?是否附加了句号?)、排序日、月和年等问题的文化规范。