Java时间处理---Java8中时区相关类库介绍

news2024/11/25 16:00:18

前言

在Java8以前,我们对于时区的处理通常是为时间转换类设置指定TimeZone,然后进行时区时间转换。

而在Java8中不仅对时间日期进行了细粒度处理,有无时区,时区处理也进行了更加细粒度的优化。

在之前我们介绍的新类库中基本都是无时区概念的。本文将引入时区概念。

 概念

介绍时区相关类库前,先来认识下Java中常见的几种时间格式

1.世界标准时间(UTC时间),其中T表示时分秒的开始,结尾的Z表示这是一个世界标准时间

2020-07-06T11:24:37.081Z

2.本地时间(不含时区信息的时间),结尾无时区信息

2020-07-06T19:24:37.156

3.含有时区信息的时间,+08:00表示该时间是由UTC时间加上8小时得到的,[Asia/Shanghai]表示该时间的时区信息

2020-07-06T19:24:37.156+08:00[Asia/Shanghai]

 ZoneId和ZoneOffSet

  • ZoneId表示一个时区实例,他的内部定义了一个地区的时区规则集,例如Europe/Paris
  • ZoneOffSet表示与UTC时间的偏移时间,格式为+08:00-04:00

 创建ZoneId

//获取系统默认时区
System.out.println(ZoneId.systemDefault());
//4种常用方式创建ZoneId
System.out.println(ZoneId.of("+01:00"));
System.out.println(ZoneId.of("UTC+01:00"));
System.out.println(ZoneId.of("America/Chicago"));
System.out.println(ZoneId.ofOffset("UTC", ZoneOffset.of("+01:00")));

输入结果:

Asia/Shanghai
+01:00
UTC+01:00
America/Chicago
UTC+01:00

创建ZoneOffSet

System.out.println(ZoneOffset.ofHours(3));
System.out.println(ZoneOffset.ofHoursMinutesSeconds(1, 2, 3));
System.out.println(ZoneOffset.of("+01:00"));

输出结果:

+03:00
+01:02:03
+01:00

单独看ZoneId和ZoneOffSet可能还不能完全看出使用效果,下面看看带时区的日期时间

ZoneDateTime

表示ISO-8601日历系统中具有时区的日期时间,此类存储所有日期和时间字段,精度为纳秒,时区为区域偏移量,用于处理模糊的本地日期时间。

例如:2020-07-06T19:24:37.156+08:00[Asia/Shanghai]

ZonedDateTime相当于拥有三个独立对象,一个本地日期时间LocalDateTime ,一个时区IDZoneId和时间偏移量ZoneOffset

偏移量和本地日期时间用于在必要时定义一个瞬时时间。 时区ID用于获取偏移量的具体规则。(因为在部分区域夏时令时的偏移量与平常不同)

来看看ZoneDateTime的常用方法

初始化

//默认系统时区
System.out.println(ZonedDateTime.now());
//指定一个时区的时间
System.out.println(ZonedDateTime.now(Clock.system(ZoneId.of("Europe/Paris"))));
//指定一个偏移量的时间
System.out.println(ZonedDateTime.now(Clock.system(ZoneOffset.of("+04:00"))));
//根据本地日期时间和系统时区组合日期时间
System.out.println(ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault()));
//根据年月日时分秒毫秒纳秒时区id构建
System.out.println(ZonedDateTime.of(2020, 1, 1, 1, 1, 1, 111, ZoneId.of("Europe/Paris")));

输出结果:

2020-07-10T11:44:15.651+08:00[Asia/Shanghai]
2020-07-10T05:44:15.653+02:00[Europe/Paris]
2020-07-10T07:44:15.668+04:00
2020-07-10T11:44:15.668+08:00[Asia/Shanghai]
2020-01-01T01:01:01.000000111+01:00[Europe/Paris]

其他方法

ZonedDateTime z = ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault());

System.out.println(z.getZone());//获取时区信息
System.out.println(z.getOffset());//获取时间偏移量
System.out.println(z.getDayOfMonth());//获取当月第几天
System.out.println(z.getDayOfWeek());//获取本周星期几
System.out.println(z.getDayOfYear());//获取本年第几天
//获取时间信息
System.out.println(z.getYear()+"/"+z.getMonthValue()+"/"+z.getDayOfMonth()+" "+
        z.getHour()+":"+z.getMinute()+":"+z.getSecond()+"."+z.getNano());
//加减时间
System.out.println(z.plusHours(3));
System.out.println(z.minusHours(3));
//修改时间
System.out.println(z.withHour(20));

输出结果

Asia/Shanghai
+08:00
10
FRIDAY
192
2020/7/10 13:37:19.37000000
2020-07-10T16:37:19.037+08:00[Asia/Shanghai]
2020-07-10T10:37:19.037+08:00[Asia/Shanghai]
2020-07-10T20:37:19.037+08:00[Asia/Shanghai]

时区与偏移量

本文开始的时候介绍了ZoneId和ZoneOffSet,在Java8中这两个类都可以对日期时间进行时区的转换,但是我更推荐使用时区信息(ZoneId),而不是时间偏移量(ZoneOffset)

首先需要重温一下概念

  • ZoneId表示一个时区实例,他的内部定义了一个地区的时区规则集,例如Europe/Paris
  • ZoneOffSet表示与UTC时间的偏移时间,格式为+08:00-04:00

这里我们以亚洲上海时间(北京时间)—>法国巴黎时间为例,对三月份的时间和六月份两个时间进行转换

ZoneId zoneId = ZoneId.of("Europe/Paris");
ZonedDateTime now = ZonedDateTime.now().withMonth(6);
System.out.println("6月的此时北京时间:"+now);
System.out.println("6月的此时巴黎时间:"+now.withZoneSameInstant(zoneId));
ZonedDateTime newTime = now.withMonth(3);
System.out.println("3月的此时北京时间:"+newTime);
System.out.println("3月的此时巴黎时间:"+newTime.withZoneSameInstant(zoneId));

输出结果:

6月的此时北京时间:2020-06-10T14:23:48.756+08:00[Asia/Shanghai]
6月的此时巴黎时间:2020-06-10T08:23:48.756+02:00[Europe/Paris]
3月的此时北京时间:2020-03-10T14:23:48.756+08:00[Asia/Shanghai]
3月的此时巴黎时间:2020-03-10T07:23:48.756+01:00[Europe/Paris]

有没有发现什么异样?

两个同一时刻不同月份的时间转换了时区后第一次偏移量为2小时,第二次为1小时

这是因为部分国家存在夏时令这种骚操作,一年中不同的月份有着不同的时间偏移量。

如果我们使用ZoneOffset,假设你知道目标时区的多种偏移时间,那么可以进行代码判断处理,但是如果要转换的时区很多,或者完全没有考虑夏时令问题时,那么转换出来的时间将会超乎你的想象!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1101406.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录:关于VScode 那点儿事

今天使用将本地的项目代码与远程服务器项目链接起来,这样就可以方便是本地编写代码,使用远程服务器调试,莫名其妙出现的问题,网上查阅了好多资料,把自己整的焦头烂额 ,记录一下: 问题1&#xf…

Python Selenium设计模式-POM

前言本文就python selenium自动化测试实践中所需要的POM设计模式进行分享,以便大家在实践中对POM的特点、应用场景和核心思想有一定的理解和掌握。 为什么要用POM 基于python selenium2开始UI级自动化测试并不是多么艰巨的任务。**只需要定位到元素,执…

UMS攸信技术助力新能源行业能效提升、驱动数据管控体系全新变革!

2023深圳国际新能源三电与智造技术产业大会2023年10月11日-10月13日在深圳国际会展中心举办,1500多名来自超过200整车厂、电池电机生产厂家的研发、生产工程技术人员参加活动,现场与会嘉宾1000多人,29场精彩演讲,共同探讨新能源行…

11+孟德尔随机化+GWAS分析

今天给同学们分享一篇凝血因子孟德尔随机化的生信文章“The effects of coagulation factors on the risk of endometriosis: a Mendelian randomization study”,这篇文章于2023年5月25日发表在BMC Med期刊上,影响因子为11.450。 子宫内膜异位症被认为是…

【MySQL】索引原理

文章目录 一、MySQL 存储与磁盘1、MySQL 存储的本质2、磁盘的物理结构3、磁盘的存储结构4、磁盘的逻辑结构5、磁盘的访问方式6、对 IO 单位的优化7、建立共识 二、索引原理1、引出索引2、如何理解 Page3、页目录与目录页4、索引结构的选择5、聚簇索引与非聚簇索引6、辅助 (普通…

【LeetCode刷题(数据结构与算法)】:合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的 **思路:定义一个头尾指针置为NULL while循环依次比较两个链表的值的大小 遍历链表 比较完数值大小过后连接到tail的尾部 然后各自的链表的节点的next指针指向下一…

短视频矩阵系统/pc、小程序版独立原发源码开发搭建上线

短视频剪辑矩阵系统开发源码----源头搭建 矩阵系统源码主要有三种框架:Spring、Struts和Hibernate。Spring框架是一个全栈式的Java应用程序开发框架,提供了IOC容器、AOP、事务管理等功能。Struts框架是一个MVC架构的Web应用程序框架,用于将数…

jq——基础操作——jq操作回顾(都忘光了。。。)

jq——基础操作——jq操作回顾 1.jq获取dom后遍历获取选中的内容2.正整数处理3.删除列表中的数据——获取每条数据是否选中(是否含有active类名)4.layer.confirm——确认提示框5.ajax——jq6.antd-table:更改整行背景色 1.jq获取dom后遍历获取选中的内容 let arr […

GeoServer改造Springboot启动一(创建springboot)

GeoServer改造Springboot启动一(创建springboot) GeoServer改造Springboot启动二(修改源码集成Swagger) GeoServer改造Springboot启动三(集成jdbcconfig和jdbcstore) GeoServer改造Springboot启动四(解决post接口方法无法用@requestbody为入参的请求) GeoServer改造…

云帆在线学习考试系统介绍

随着网络技术的不断发展,越来越多的人开始意识到在线学习和考试的重要性。在这个数字化时代,借助互联网平台,人们可以轻松地获取各种知识和技能,提升自己的竞争力。而云帆在线学习考试系统正是在这样的背景下应运而生的。云帆在线…

MySQL配置环境变量和启动登录

如果不配置环境变量,每次登录 MySQL 服务器时就必须进入到 MySQL 的 bin 目录下,也就是输入“cd C:\Program Files\MySQL\MySQL Server 5.7\bin”命令后,才能使用 MySQL 等其它命令工具,这样比较麻烦。配置环境变量以后就可以在任…

ES6 新特性重点部分

目录 一、ES6简介 二、ES6新特性 1.let变量声明 : 2.const常量声明 : 3.解构赋值 : 3.1 解构赋值简介 3.2 数组解构 3.3 对象解构 4.模板字符串 : 5.对象简写 : 6.运算符扩展 : 7.箭头函数 : 7.1 简介 7.2 实例 8.ES6---Promise : 9.ES6---模块化编程 : 一、ES6简介…

算法通过村第十五关-超大规模|青铜笔记|海量找数

文章目录 前言用4KB内存寻找重复数总结 前言 提示:并不是所有黑暗的地方,都需要光明。 --珍妮特温特森《句子不是唯一的水果》 在大部分算法中,默认给点给的数据量都是很小的,例如只有几个或者十几个元素,但是如果遇到…

如何定量对比两个图分类数据集的分布

以下来自gpt,若有勘误,欢迎指正: (图片来自links ,侵删) 对于两个图分类数据集的分布,我们可以使用一些统计指标来进行定量对比。下面介绍一些常用的指标: 图分类准确率 图分类准确…

性能测试的指南:测试类型、性能测试步骤、最佳实践等

近期公司为了节省成本搞了一波机房迁移,整合了一些南美部署架构。有一些上google云和有些下阿里云等大的调整。 在做机房迁移项目当中就需要思考如何进行性能测试,这种大的机房迁移SRE(运维)会针对组件会做一些单组件的性能测试&a…

如何通过代码混淆绕过苹果机审,解决APP被拒问题

如何通过代码混淆绕过苹果机审,解决APP被拒问题 目录 iOS代码混淆 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD5 info.plist文件添加垃圾字段 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD…

aidl的注意事项

该篇继承自上一篇,上一篇也有一部分的注意事项,这一篇把其他的情况列出 一 客户段和服务端的aidl文件下的package名字要是一样的 二 server中的 manifest中的package名字,这个与上面两个包不能相同,不然在客户端设置intent的pa…

Vulnhub靶场之matrix-breakout-2-morpheus

简介: vulnhub是一个提供靶场环境的平台。今天从首页下载了一个来做,它叫matrix-breakout-2-morpheus。 项目下载地址:Matrix-Breakout: 2 Morpheus ~ VulnHub 0x01 信息收集 查看本机IP,靶机跟kali都是使用NAT模式,所…

【QT开发(4)】Qt Creator编译器修改,应用程序二进制接口(ABI)的版本;API、ABI、系统调用是什么?版本的选择(ABI和CPU版本)

文章目录 1.编译器的简介2 应用程序二进制接口(ABI)的版本3 API、ABI、系统调用是什么,以及这三个词的区别。3.1 什么是API?3.2 什么是ABI?3.3 API和系统调用有什么区别 4 Qt for Android——关于版本的选择(ABI和CPU版本)参考 1.编译器的简介 编译器…

【Linux】adduser命令使用

我们经常在linux系统中创建用户。有时候用的是 useradd 有时候用的是 adduser ,好混乱啊到底用哪个啊。今天咱们一起来学习一下。 adduser与useradd的区别 useradd 命令是内置的 Linux 命令,在任何 Linux 系统中都可用。然而,使用这种低级…