彻底弄透Java处理GMT/UTC日期时间( 二 )

运行程序 , 输出(大部分符合规律:/前表示所属州 , /表示城市名称):
可用zoneId总数:628Africa/AbidjanAfrica/Accra...Asia/Chongqing // 亚洲/重庆Asia/Shanghai // 亚洲/上海Asia/Dubai // 亚洲/迪拜...America/New_York // 美洲/纽约America/Los_Angeles // 美洲/洛杉矶...Europe/London // 欧洲/伦敦...Etc/GMTEtc/GMT+0Etc/GMT+1...值得注意的是并没有 Asia/Beijing 哦 。

说明:此结果基于JDK 8版本 , 不同版本输出的总个数可能存在差异 , 但主流的ZoneId一般不会有变化
方式二: zoneId的列表是jre维护的一个文本文件 , 路径是你JDK/JRE的安装路径 。地址在.jrelib目录的为未tzmAppings的文本文件里 。打开这个文件去ctrl + f找也是可以达到查找的目的地 。
这两种房子可以帮你找到ZoneId的字典方便查阅 , 但是还有这么一种情况:当前所在的城市呢 , 在tzmappings文件里根本没有(比如没有收录) , 那要获取这个地方的时间去显示怎么破呢?虽然概率很小 , 但不见得没有嘛 , 毕竟全球那么多国家那么多城市呢~
Java自然也考虑到了这一点 , 因此也是有办法的:指定其时区数字表示形式 , 其实也叫偏移量(不要告诉我这个地方的时区都不知道 , 那就真没救了) , 如下示例
@Testpublic void test4() {    System.out.println(TimeZone.getTimeZone("GMT+08:00").getID());    System.out.println(TimeZone.getDefault().getID());    // 纽约时间    System.out.println(TimeZone.getTimeZone("GMT-05:00").getID());    System.out.println(TimeZone.getTimeZone("America/New_York").getID());}运行程序 , 输出:
GMT+08:00 // 效果等同于Asia/ShanghaiAsia/ShanghaiGMT-05:00 // 效果等同于America/New_YorkAmerica/New_York 值得注意的是 , 这里只能用GMT+08:00 , 而不能用UTC+08:00 , 原因下文有解释 。
设置默认时区一般来说 , JVM在哪里跑 , 默认时区就是哪 。对于国内程序员来讲 , 一般只会接触到东八区 , 也就是北京时间(本地时间) 。随着国际合作越来越密切 , 很多时候需要日期时间国际化处理 , 举个很实际的例子:同一份应用在阿里云部署、在AWS(海外)上也部署一份供海外用户使用 , 此时同一份代码部署在不同的时区了 , 怎么破?
倘若时区不同 , 那么势必影响到程序的运行结果 , 很容易带来计算逻辑的错误 , 很可能就乱套了 。Java让我们有多种方式可以手动设置/修改默认时区:
  1. API方式: 强制将时区设为北京时区TimeZone.setDefault(TimeZone.getDefault().getTimeZone("GMT+8"));
  2. JVM参数方式:-Duser.timezone=GMT+8
  3. 运维设置方式:将操作系统主机时区设置为北京时区 , 这是推荐方式 , 可以完全对开发者无感 , 也方便了运维统一管理
据我了解 , 很多公司在阿里云、腾讯云、国内外的云主机上部署应用时 , 全部都是采用运维设置统一时区:中国时区 , 这种方式来管理的 , 这样对程序来说就消除了默认时区不一致的问题 , 对开发者友好 。
让人恼火的夏令时你知道吗 , 中国曾经也使用过夏令时 。
什么是夏令时?
离现在最近是1986年至1991年用过夏令时(每年4月中旬的第一个周日2时 - 9月中旬的第一个星期日2时止): 


推荐阅读