| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 高级JAVA开发必须掌握技能java8 新日期时间API((一)JSR-310:ZoneId 时区和偏移量),2万字详解(全程干货,建议收藏) -> 正文阅读 |
|
[Java知识库]高级JAVA开发必须掌握技能java8 新日期时间API((一)JSR-310:ZoneId 时区和偏移量),2万字详解(全程干货,建议收藏) |
大家好,我是小虚竹。之前有粉丝私聊我,问能不能把JAVA8 新的日期时间API(JSR-310)知识点梳理出来。答案是肯定的,谁让我宠粉呢。由于内容偏多(超十万字了),会拆成多篇来写。 闲话就聊到这,请看下面的正文。 第一节:概念知识时区
时区经度分布如列表所示:
实际上,常常1个国家或1个省份同时跨着2个或更多时区,为了照顾到行政上的方便,常将1个国家或1个省份划在一起。例如,中国幅员宽广,差不多跨5个时区,但为了使用方便简单,实际上在只用东八时区的标准时即北京时间为准。 UTC
协调世界时跟地区位置没有相关,不代表当前时刻某个地方的时间,所以在说某个地方时间时要加上时区。例如:中国就是UTC+8。 UTC是时间标准,这个标准把世界分成UTC-12到UTC+12共24个时区。 GMTGMT(Greenwich Mean Time)别名:格林尼治时间(有时候翻译也叫格林威治),中文名:世界时。
GMT并不等于UTC,只是格林尼治刚好在0时区上。所以GMT = UTC+0才是对的。 CST
所以在换算CST时间时,要注意对应的时区。这是一个坑。 美国中部时间:CST=UTC/GMT-6; 中国标准时间:CST=UTC/GMT+8; DSTDST(Daylight Saving Time)中文名:夏令时。
中国实现DST时间范围:1986年至1991年。 ISO-8601
年由4位数字组成YYYY,或者带正负号的四或五位数字表示±YYYYY。以公历公元1年为0001年,以公元前1年为0000年,公元前2年为-0001年。 月、日用两位数字表示:MM、DD。 只使用数字为基本格式。使用短横线"-"间隔开年、月、日为扩展格式。 小时、分和秒都用2位数表示,对UTC时间最后加一个大写字母Z,其他时区用实际时间加时差表示。如UTC时间下午2点30分5秒表示为14:30:05Z或143005Z,当时的北京时间表示为22:30:05+08:00或223005+0800,也可以简化成223005+08。 注:大家还记得java的Date类吗?它默认就是使用ISO-8601表示的。 第二节:JDK8之前:时区/偏移量TimeZone在JDK8之前,我们一直用java.util.TimeZone来表示和处理时区和偏移量。 TimeZone.getDefault() 获得当前JVM所运行的时区,那它是怎么获取默认时区的呢,之前有写过分析文章,有兴趣的可以了解下,这里就不再重复了。 有时候需要做时区的时间转换,比如一个时间要用北京时间和纽约时间显示。实现: 这里没有到SimpleDateFormat 来格式化时间是因为它是线程不安全的。选用线程安全的FastDateFormat, Apache Commons Lang包支持。 有兴趣可以了解下FastDateFormat 的源码分析:java的SimpleDateFormat线程不安全出问题了,虚竹教你多种解决方案
19-7=12 北京时间比纽约时间快12小时。 第三节:JDK8开始支持:时区/偏移量 ZoneId/ZoneOffsetJDK8中ZoneId表示时区的ID,ZoneOffset表示Greenwich/UTC的偏移量。 ZoneId 是用来替换java.util.TimeZone 的。 我们来研究下ZoneId ,ZoneId代表一个时区的ID,它是确定的。但是时区ID是有对应的规则,规则变化为java.time.zone.ZoneRules 决定。像夏令时规则是由各国政府定的,可能会变化,不同的年还不一样,这个就交给JDK底层机制来保持同步,我们调用者不需要关心(不!要关心!当技术不再是黑盒时,才能做到心里有底! )。 时区的规则发生变化时,如何同步时区TZUpdater 工具介绍? 提供的 TZUpdater 工具 允许您使用更新的时区数据更新已安装的 Java 开发工具包 (JDK) 和 Java 运行时环境 (JRE) 软件,以适应不同国家/地区的夏令时 (DST) 更改。Oracle 依赖于通过 IANA 的时区数据库公开提供的时区数据。 如果您无法使用 Oracle 最新的 JDK 或 JRE 更新版本,或者如果最新版本上的时区数据不是最新可用的,TZUpdater 工具提供了一种更新时区数据的方法,同时保持其他系统配置和依赖项不变. TZUpdater 工具用法TZUpdater 工具用于执行该工具的 JDK/JRE 软件实例。每次执行都会修改 JDK/JRE 软件。要将工具管理到 JDK/JRE 软件的多个实例。 在安装的 JDK/JRE 软件上运行 TZUpdater 工具之前,您必须停止操作系统上的 JDK/JRE 软件的任何正在运行的服务。 使用以下命令运行 TZUpdater 工具:
要成功更新时区数据,您应该确保您有足够的权限来修改 如果未指定任何选项,则会显示用法消息。要更新时区数据,请使用
手动升级注意: 1、在安装的 JDK/JRE 软件上运行 TZUpdater 工具之前,您必须停止操作系统上的 JDK/JRE 软件的任何正在运行的服务。 2、要成功更新时区数据,您应该确保您有足够的权限来修改 3、如果系统上有多个JDK/JRE ,需要将该工具用于每个JDK/JRE中(每个JDK/JRE都要操作一遍) 4、更新成功后,要重新启动此 JDK/JRE 实例上的应用程序服务(如果还没更新,重启下服务器试试) 操作步骤:1、下载Oracle官方提供的tzupdater.jar包;下载地址 https://www.oracle.com/java/technologies/javase-tzupdater-downloads.html 把tzupdater.jar放到java目录bin目录下,比如
2、查看当前时区数据库版本,以windows为例,用管理员身份运行cmd,切换到tzupdater.jar对应的目录:
3、在线更新,以windows为例,用管理员身份运行cmd,切换到tzupdater.jar对应的目录:(第3种和第4种更新方式任选一种)
如图所示,已经更新成功到了tzdata2021a版本了。 更新后的文件是放在jre/lib/tzdb.dat ,如图所示,它有备份历史的版本。 4、离线更新:要先下载最新的时区数据,下载地址: https://data.iana.org/time-zones/releases/ 以windows为例,用管理员身份运行cmd。切换到tzupdater.jar对应的目录:
注: windows建议放在C盘根目录下,路径目录也不要有中文; 用管理员身份运行cmd(需要写权限); 如上面的命令所示,file后面的/是3个 5、以上执行完后,用第2步的查看当前时区数据库版本命令,查看是否更新成功。 服务自动化升级思路步骤:1、设置定时任务(操作系统配置就行),执行tzupdater 更新时区的命令脚本; 2、新开一个时区服务,用来对外提供时区和夏令时规则读取服务,独立部署; 3、在时区服务中,写个同步按钮,用来执行tzupdater 更新时区的命令脚本; 4、在时区服务中,将timeZone数据定时写到自定义的时区表中。提供维护功能,可以自定义新增修改删除timeZone数据。 此思路的好处:1、其他服务不需要停止服务来更新时间,直接通过调用时区服务的数据,可保证获取到最新的时区数据; 2、自动化的好处,避免了手动维护时区的繁琐,人工介入有引发问题的风险; 3、时区服务和其他业务服务是拆分的,方便未来的扩展。 系统默认的ZoneId
所以两个的结果是一样的(Asia/Shanghai),这个很正常。 TimeZone.toZoneId() 是java8 后加的方法。
指定字符串得到ZoneId和获取所有的zoneIds
指定的字符串不能乱写,不然会报错,要在ZoneId.getAvailableZoneIds() 的集合范围里。 从日期中获取时区
从日期中获取时区只支持带有时区的TemporalAccessor ,像LocalDateTime,LocalDate是不可以的,会报错。
ZoneId是抽象类,它有两个继承实现类:
ZoneOffset(时区偏移量)时区偏移量是时区与Greenwich/UTC之间的时间差,一般是固定的小时数和分钟数。 最小/最大偏移量
超出最大范围会报错 时分秒构造偏移量
挺方便的,也简单好理解。偏移量可以精确到秒级。 ZoneRegion(地理区域)ZoneRegion表示地理区域,格式是:洲(州、国家)/城市。最常见的区域分类是时区数据库(TZDB)。 which defines regions such as ‘Europe/Paris’ and ‘Asia/Tokyo’.(TZDB使用“Europe/Paris”和“Asia/Tokyo”来区分地区。)
由源码可知,地理区域ZoneRegion是ZoneId的继承实现类。 但是我们发现这个不是对外使用的,ZoneRegion的修饰符是default(只能由同包下的类调用)。只能通过ZoneId来操作。
博主在厦门,所以默认获取的时区ID是Asia/Shanghai。 ZoneId的实例是ZoneOffset或ZoneRegionZoneId of(String zoneId, boolean checkAvailable) 源码分析:
由源码可知:
推荐相关文章hutool日期时间系列文章2DateUtil(时间工具类)-常用的时间类型Date,DateTime,Calendar和TemporalAccessor(LocalDateTime)转换 9LocalDateTimeUtil(JDK8+中的{@link LocalDateTime} 工具类封装) 10TemporalAccessorUtil{@link TemporalAccessor} 工具类封装 其他java的SimpleDateFormat线程不安全出问题了,虚竹教你多种解决方案 参考:JSR-310:新日期时间API(一)时区:https://baike.baidu.com/item/%E6%97%B6%E5%8C%BA/491122?fr=aladdin UTC:https://baike.baidu.com/item/%E5%8D%8F%E8%B0%83%E4%B8%96%E7%95%8C%E6%97%B6/787659?fromtitle=UTC&fromid=5899996&fr=aladdin GMT:https://baike.baidu.com/item/%E4%B8%96%E7%95%8C%E6%97%B6/692237?fromtitle=GMT&fromid=6026868&fr=aladdin CST:https://baike.baidu.com/item/CST/14822063?fr=aladdin DST:https://baike.baidu.com/item/%E5%A4%8F%E4%BB%A4%E6%97%B6/1809579?fromtitle=DST&fromid=1203186&fr=aladdin ISO-8601:https://baike.baidu.com/item/ISO%208601/3910715?fr=aladdin TZUpdater :https://www.oracle.com/java/technologies/javase/tzupdater-readme.html IANA时区数据版本:https://data.iana.org/time-zones/releases/ JRE 软件中的时区数据版本:https://www.oracle.com/java/technologies/tzdata-versions.html |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 9:57:17- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |