今天来说说时区和时间。这个问题在新手刚接触的时候总是搞得似懂非懂,所以这里只是把最容易搞混的地方来捋清楚,不专门针对API进行讲解。

GMT和UTC时间区别与联系

GMT时间

GMT(Greenwich Mean Time),格林威治时间。这是英国的格林威治皇家天文台为了海上霸权的扩张计划,在十七世纪就开始进行天体观测。为了天文观测,选择了穿过伦敦格林威治天文台子午仪中心的一条经线作为零度参考线,这条线,简称格林威治子午线。

它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午12点。很显然,因为地球每天的自转是不规则的(正在缓慢减速)所以,格林尼治时间的精确度会越来越低,但是依照地球每天的自转而制定的时间非常符合人的认知,所以说很适用。

1884年10月,在美国华盛顿召开了一个国际子午线会议,该会议将格林威治子午线设定为本初子午线,并将格林威治时间作为世界基准时间(UT, Universal Time)。由此也确定了全球24小时自然时区的划分,所有时区都以和GMT 之间的偏移量做为参考。

时区概念

世界基准时间时区定义如下:

从格林威治本初子午线起,经度每向东或者向西间隔15°,就划分一个时区,在这个区域内,大家使用同样的标准时间。全球共分为24个标准时区,相邻时区的时间相差一个小时。

1972年之前,格林威治时间(GMT)一直是世界时间的标准。1972年之后,GMT不再是一个时间标准了。

UTC

显然,无论是GMT时间还是世界基准时间,其实都不是很精确,那么不禁要问,找一个绝对精确的绝对时间不就行了?

很显然,这不现实的。因为人类所能直接感知的时间就是日升日落(地球自转),因为这种符合作息规律才更容易被人接受和使用。想想全世界都用一种基于原子钟的精确时间,有的地方是日上三竿,有的地方是漫漫黑夜,交流起来岂不是更加困难?

因此,为了既要精确,又要不违背实际的天文规律,UTC时间诞生了。

UTC(Coodinated Universal Time),协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。

UTC是现在全球通用的时间标准,全球各地都同意将各自的时间进行同步协调。

UTC 时间是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以秒为单位的国际原子时所综合精算而成:因为地球自转越来越慢,每年都会比前一年多出零点几秒,每隔几年协调世界时组织都会给世界时+1秒,让基于原子钟的世界时和基于天文学(人类感知)的格林威治标准时间相差不至于太大。

所以,UTC与GMT基本上等同,但是如果要算时间差,肯定是用UTC时间更加精确,此外,UTC时间专指格林威治时间,所以全世界其他地方的时间都要加一个偏移量来表示。

UTC时间的表示

如上文所说,UTC时间要带上时区,那么很显然,UTC时间可以表示如下:

第一种:直接带上时区

类型 示例
日期:年 1997
日期:年月 1997-07
日期:年月日 1997-07-16
日期加小时和分钟 1997-07-16T19:20+01:00
日期加小时、分钟和秒钟 1997-07-16T19:20:30+01:00
日期加小时、分钟、秒钟和秒钟的小数部分 1997-07-16T19:20:30.45+01:00

其中:

  • YYYY = 四位数年份

  • MM = 月份,从 01 到 12 的两位数

  • DD = 几号,从 01 到 31 的两位数

  • T = 在日期后时间前的文本值

  • hh = 小时,从 00 到 23 的两位数

  • mm = 分钟,从 00 到 59 的两位数

  • ss = 秒钟,从 00 到 59 的两位数

  • SSS = 一或多位数,表示秒的小数部分

  • 后面的+或者-表示时间的偏移量。

第二种,不带时区,但是明确指出这是UTC时间

如果不带时区指示符,那么,末尾应该带上一个“Z”,表示这是UTC时间而非本地时间。比如说:2015-08-03T07:21:33Z。转换成北京时间就是2015-08-03 15:21:33

下面用代码来说明一下:

Instant now = Instant.now();
Instant gmt = now.atOffset(ZoneOffset.UTC).toInstant();
System.out.println(gmt.toString());
复制代码

输出:

2023-04-14T10:26:27.563Z
复制代码

我写这篇文章时,上面输出的时间+8小时就是北京时间。

请注意,现在通用的就是UTC时间,不用考虑别的时间格式。那种末尾带上GMT标识的时间,JDK已经默认不支持,如果硬要输出带GMT标识的时间,自己用SimpleDateFormat转换吧!

而在JDK8以前,正是因为没有把GMT和UTC区分的很好,导致Java时区一直非常混乱……所以,请把GMT扔进垃圾堆!

ISO其实规定了很多的时间格式,Java的DateTimeFormatter规定如下的合法格式:

常量 说明 示例
BASIC_ISO_DATE Basic ISO date '20111203'
ISO_LOCAL_DATE ISO Local Date '2011-12-03'
ISO_OFFSET_DATE ISO Date with offset '2011-12-03+01:00'
ISO_DATE ISO Date with or without offset '2011-12-03+01:00'; '2011-12-03'
ISO_LOCAL_TIME Time without offset '10:15:30'
ISO_OFFSET_TIME Time with offset '10:15:30+01:00'
ISO_TIME Time with or without offset '10:15:30+01:00'; '10:15:30'
ISO_LOCAL_DATE_TIME ISO Local Date and Time '2011-12-03T10:15:30'
ISO_OFFSET_DATE_TIME Date Time with Offset '2011-12-03T10:15:30+01:00'
ISO_ZONED_DATE_TIME Zoned Date Time '2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_DATE_TIME Date and time with ZoneId '2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_ORDINAL_DATE Year and day of year '2012-337'
ISO_WEEK_DATE Year and Week '2012-W48-6'
ISO_INSTANT Date and Time of an Instant '2011-12-03T10:15:30Z'
RFC_1123_DATE_TIME RFC 1123 / RFC 822 'Tue, 3 Jun 2008 11:05:30 GMT'

2.关于时区&偏移量

在JDK 8之前,Java使用java.util.TimeZone来表示时区。而在JDK8里分别使用了ZoneId表示时区ZoneOffset表示UTC的偏移量

值得强调的是,时区和偏移量在概念和实际作用上是有较大区别的,主要体现在:

  1. UTC偏移量仅仅记录了偏移的小时分钟而已,除此之外无任何其它信息。举个例子:+08:00的意思是比UTC时间早8小时,没有地理/时区含义,相应的-03:30代表的意思仅仅是比UTC时间晚3个半小时

  2. 时区是特定于地区而言的,它和地理上的地区(包括规则)强绑定在一起。比如整个中国都叫东八区,纽约在西五区等等

中国没有夏令时,所有东八区对应的偏移量永远是+8;纽约有夏令时,因此它的偏移量可能是-4也可能是-5。

综合来看,时区更好用。令人恼火的夏令时问题,若你使用UTC偏移量去表示那么就很麻烦,因为它可变:一年内的某些时期在原来基础上偏移量 +1,某些时期 -1;但若你使用ZoneId时区去表示就很方便喽,比如纽约是西五区,你在任何时候获取其当地时间都是能得到正确答案的,因为它内置了对夏令时规则的处理,也就是说啥时候+1啥时候-1时区自己门清,不需要API调用者关心。

如果将时区写死成偏移量,在没有时区规则(没有夏令时)的国家不会存在问题,东八区和UTC+08:00效果永远一样。但在一些夏令时国家(如美国、法国等等),就只能根据时区去获取当地时间,所以当你不了解当地规则时,最好是使用时区而非偏移量。

ZoneId

它代表一个时区的ID,如Europe/Paris。它规定了一些规则可用于将一个Instant时间戳转换为本地日期/时间LocalDateTime。

上面说了时区ZoneId是包含有规则的,实际上描述偏移量何时以及如何变化的实际规则由java.time.zone.ZoneRules定义。ZoneId则只是一个用于获取底层规则的ID。之所以采用这种方法,是因为规则是由政府定义的,并且经常变化,而ID是稳定的

可以在这里查看标准时区ID:标准时区ID

因此,要用ZoneId来作为时区。不能单纯用偏移量。

关于Unix时间戳与Instant

Unix时间(Unix Time),是计算机世界的时间,也叫做POSIX时间或纪元时间(Epoch Time),是用来记录时间的流逝,所以也常被叫做时间戳。

定义为从1970-01-01T00:00:00开始流逝的秒数,不考虑闰秒。之后的时间是正数,之前的是负数。

从定义可以看到,它只代表了从Unix纪元开始流逝的秒数,所以你身处地球上何处,这个时间都是一样的。

一般Unix时间都是精确到秒,但也有些地方Unix时间是精确到毫秒的(比如MySQL 5.6.4之后开始支持到微秒)

Unix时间不是凭空产生的,他就是UTC时间在计算机世界的表达。

Unix时间戳是从1970年1月1日(UTC+00)开始所经过的秒数,不考虑闰秒。时间戳表示的时间是准确、恒定的。就连时间+日期+时区也不行——时区不是恒定不变的,这是一个全球统一的绝对时间。

因此,如果说我们不想对时区进行各种转换,那么最好是存储Unix时间戳,再转换成对应的UTC带时区时间,或者直接存储UTC时间。

Instant

Instant类返回的值计算从 1970 年 1 月 1 日(1970-01-01T00:00:00Z)第一秒开始的时间(精确到纳秒),也称为 EPOCH。 发生在时期之前的瞬间具有负值,并且发生在时期后的瞬间具有正值,因此这个时间就等于UTC时间。

String output = instant.toString();
复制代码

输出:

2023-02-20 T19:15:25.864Z
复制代码

Instant简单理解为就是用一个对象来表示unix时间戳。时间等于当前的UTC时间

作者:徐家三少
链接:https://juejin.cn/post/7221825086667440189

对计算机世界中的时区和时间分类总是似懂非懂?看这一篇文章就够了相关推荐

  1. python中定义元组的符号_python中得元组和字符串详解,有这么一篇文章就够了

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 以下文章来源于腾讯云 作者:咸鱼学Python ( 想要学习Python?Pyth ...

  2. 猿如意中的【ApiFox】工具的安装与使用教程,超详细,保姆级教程看这一篇文章就够了。

    目录 一.什么是猿如意 二.猿如意中下载安装 ApiFox 2.1.如何下载和安装 2.2.什么是 ApiFox? 三.关于 ApiFox 的介绍以及使用 1.基本介绍 2.支持API文档导入 3.接 ...

  3. 【Linux基础】Linux中的时区和时间

    基本概念 首先介绍Linux中会用到的时间概念: UTC:Universal Time Coordinated,协调世界时,又称世界统一时间,世界标准时间,国际协调时间.它是一个与时区相关的时间,目前 ...

  4. 软件测试工作中需要的Linux知识,一篇文章就够了

    01 Linux基础 1.Linux系统简单介绍 Linux是一套免费使用, 支持多用户.多任务.支持多线程和多个核心CPU的操作系统:很多中型, 大型甚至是巨型项目都在使用Linux. Linux的 ...

  5. mysql当前时间往后推一周_一篇文章搞定Mysql日期时间函数

    前言 日期和时间函数部分也是我们日常工作中使用频率比较高的一部分.这一篇我们主要讲讲mysql里面的日期时间相关的函数,不同数据库之间基本相同,只会有个别函数的差异.大家掌握一个数据库的,其他的遇到不 ...

  6. 学习多线程中的 Future 模式一篇文章就够了 !!!

    文章目录 一.Future 模式 二.Future模式的主要角色 三.Future模式的简单实现 四.JDK中的Future模式 五.Guava对Future模式的支持 一.Future 模式 Fut ...

  7. go 函数名之前括号中的内容_2020 重学 Go 系列:09. 一篇文章理解 Go 里的函数

    1. 关于函数 函数是基于功能或 逻辑进行封装的可复用的代码结构.将一段功能复杂.很长的一段代码封装成多个代码片段(即函数),有助于提高代码可读性和可维护性. 在 Go 语言中,函数可以分为两种: 带 ...

  8. 为什么在ftp的配置中linux和windowns ping不通_2019年电脑配置推荐,收藏一篇文章就够了...

    [2019年]建议您按照如下5种档次选择适合自己的电脑,文章较长建议收藏后阅读 去年intel涨价太多,目前价格已经下跌,但仍然没有回落到起涨点,在性价比上有明显劣势.不过,intel可不是吃素的,面 ...

  9. Java 中按文件名称分类,按文件大小分类,按照文件类型分类,按照最后修改时间分类的工具类

    在此博客中用到了文件操作的工具类,可以连接 Java中实现复制文件到文件,复制文件到文件夹,复制文件夹到文件,删除文件,删除文件夹,移动文件,移动文件夹的工具类 package cn.edu.hact ...

最新文章

  1. android post请求_Vue 网络请求框架 axios 使用教程
  2. iOS架构-静态库.framework手动打包及脚本化打包(5)
  3. MediaPlayer loading 问题解决
  4. 清华大学计算机系人机交互,喻 纯 - 清华大学 - 《自然人机交互中的智能输入》(47页)-原创力文档...
  5. 【C 语言】文件操作 ( 文件加密解密 | 加密解密原理 | 对称加密 | 非对称加密 | 散列函数 )
  6. 应用新安全组 - 每天5分钟玩转 OpenStack(116)
  7. Tiniux 3.0 / Memory.c / OSMemFree
  8. SQL基础【六、and与or】
  9. git仓库的基本用法
  10. 程序员操作系统推荐_为什么程序员要会 Linux
  11. 这段 Python 代码让程序员赚 300W,公司已确认!网友:神操作!
  12. 【Git】GitHub同名项目实现丰富多彩的README.md
  13. Page.ClientScript.RegisterArrayDeclaration
  14. php防伪溯源x系统_区块链溯源防伪追溯系统开发解决方案
  15. 万维网文档在服务器端动态,信息网络应用基础作业2.docx
  16. c#连接kafka_c#操作kafka(上)搭建kafka环境
  17. 安卓手机小说阅读器_粉笔免费小说阅读器app下载-粉笔免费小说阅读器手机版下载v1.0.1...
  18. 耗时86小时的「百变小樱」最强数据可视化作品!| 译文
  19. java项目word转换成pdf并且去除水印
  20. 浙大计算机能保研到交大多吗6,保研之路:她来自双非高校,却同时保研到交大、浙大,有啥经验?...

热门文章

  1. 数据分析——人员分析
  2. 大学四年,如果高质量的度过?(非鸡汤,本人已保研中科大,8000字干货)
  3. 安卓手机重启日志_安卓手机系统一直不升级会怎么样?
  4. 教学录像分析 计算机,课堂教学录像分析方法 - 敏特英语.ppt
  5. 安卓手机反应越来越慢怎么办_安卓手机怎么越用越慢?终于知道怎么解决了 这招太好用了!...
  6. 修复AirPods不断与iPhone断开连接的10种方法
  7. vue中上传读取及下载excel文件
  8. ecshop {insert name='comments' type=$type id=$id} 什么意思
  9. 对某一比赛参赛队基本信息进行管理
  10. php怎么设置文字环绕图片,css文字环绕图片的方法