共计 3060 个字符,预计需要花费 8 分钟才能阅读完成。
- ZoneId 为时区 ID,比方 Europe/Paris,示意欧洲巴黎时区
1.1 时区相干常识,时区,UTC 工夫,GMT 工夫,Unix 工夫戳
时区
地球自西向东旋转,东边比西边先看到太阳,东边的工夫也比西边的早。为了对立世界的工夫,1884 年的国内经度会议规规定将寰球划分为 24 个时区(东、西各 12 个时区)。规定英国(格林尼治天文台原址)为零时区(GMT+00),东 1 -12 区,西 1 -12 区,中国北京处于东 8 区(GMT+08)。
若英国工夫为 6 点整,则 GMT 工夫为 6 点整,则北京工夫为 14 点整。
GMT 和 UTC
GMT,即格林尼治规范工夫,也就是世界时。GMT 的正午是指当太阳横穿格林尼治子午线(本初子午线)时的工夫。但因为地球自转不平均不规则,导致 GMT 不准确,当初曾经不再作为世界规范工夫应用。
UTC,即协调世界时。UTC 是以原子时秒长为根底,在时刻上尽量靠近于 GMT 的一种工夫计量零碎。为确保 UTC 与 GMT 相差不会超过 0.9 秒,在有须要的状况下会在 UTC 内加上正或负闰秒。UTC 当初作为世界规范工夫应用。
所以,UTC 与 GMT 基本上等同,误差不超过 0.9 秒。
UNIX 工夫戳
计算机中的 UNIX 工夫戳,是以 GMT/UTC 工夫「1970-01-01T00:00:00」为终点,到具体工夫的秒数,不思考闰秒。这么做当然是为了简化计算机对工夫操作的复杂度。
比方我的电脑当初的零碎工夫为 2015 年 2 月 27 日 15 点 43 分 0 秒,因为我的电脑默认时区为东 8 区,则 0 时区的工夫为 2015 年 2 月 27 日 7 点 43 分 0 秒,则 UNIX 工夫戳为 1425022980 秒。
每个 Java 开发人员都应该至多理解这套新的 API 中的这五个类:
●Instant 它代表的是工夫戳,比方 2016-04-14T14:20:13.592Z,这能够从 java.time.Clock 类中获取,像这样:Instant current = Clock.system(ZoneId.of(“Asia/Tokyo”)).instant();
●LocalDate 它示意的是不带工夫的日期,比方 2016-04-14。它能够用来存储生日,周年纪念日,入职日期等。
●LocalTime – 它示意的是不带日期的工夫
●LocalDateTime – 它蕴含了工夫与日期,不过没有带时区的偏移量
●ZonedDateTime – 这是一个带时区的残缺工夫,它依据 UTC/ 格林威治工夫来进行时区调整
●这个库的主包是 java.time,外面蕴含了代表日期,工夫,刹时以及持续时间的类。它有两个子 package,一个是 java.time.foramt,这个是什么用处就很显著了,还有一个是 java.time.temporal,它能从更低层面对各个字段进行拜访。
●时区指的是地球上共享同一规范工夫的地区。每个时区都有一个惟一标识符,同时还有一个地区 / 城市 (Asia/Tokyo) 的格局以及从格林威治工夫开始的一个偏移工夫。比如说,东京的偏移工夫就是 +09:00。
●OffsetDateTime 类实际上蕴含了 LocalDateTime 与 ZoneOffset。它用来示意一个蕴含格林威治工夫偏移量(+/- 小时:分,比方 +06:00 或者 -08:00)的残缺的日期(年月日)及工夫(时分秒,纳秒)。
●DateTimeFormatter 类用于在 Java 中进行日期的格式化与解析。与 SimpleDateFormat 不同,它是不可变且线程平安的,如果需要的话,能够赋值给一个动态变量。DateTimeFormatter 类提供了许多预约义的格局器,你也能够自定义本人想要的格局。当然了,依据约定,它还有一个 parse()办法是用于将字符串转换成日期的,如果转换期间呈现任何谬误,它会抛出 DateTimeParseException 异样。相似的,DateFormatter 类也有一个用于格式化日期的 format()办法,它出错的话则会抛出 DateTimeException 异样。
●再说一句,“MMM d yyyy”与“MMm dd yyyy”这两个日期格局也略有不同,前者能辨认出 ”Jan 2 2014″ 与 ”Jan 14 2014″ 这两个串,而后者如果传进来的是 ”Jan 2 2014″ 则会报错,因为它冀望月份处传进来的是两个字符。为了解决这个问题,在天为个位数的状况下,你得在后面补 0,比方 ”Jan 2 2014″ 应该改为 ”Jan 02 2014″。
Instant:工夫戳,相当于 java.util 的 Date
LocalDate:只蕴含日期,比方:2016-10-20
LocalTime:只蕴含工夫,比方:23:12:10
LocalDateTime:蕴含日期和工夫,比方:2016-10-20 23:14:21
Duration:计算两个“工夫”的距离
Period:用于计算两个“日期”的距离
ZoneOffset:时区偏移量,比方:+8:00
ZonedDateTime:能够失去特定时区的日期 / 工夫
Clock:时钟,比方获取目前美国纽约的工夫
Clock 类提供了拜访以后日期和工夫的办法,Clock 是时区敏感的,能够用来取代 System.currentTimeMillis() 来获取以后的微秒数。某一个特定的工夫点也能够应用 Instant 类来示意,Instant 类也能够用来创立老的 java.util.Date 对象。
Clock clock = Clock.systemDefaultZone();
long millis = clock.millis();
Instant instant = clock.instant();
Date legacyDate = Date.from(instant); // legacy java.util.Date
偏移量 VS 时区
一个 UTC 偏移量 offset-from-UTC 仅仅只记录了时分秒而已,除此之外没有任何其余信息。举个例子,+08:00 的意思时超前于 UTC 八个小时,而 -05:45 意思是落后于 UTC 五小时四十五分钟。
而时区对于特定地区的人来说是过来,当初,将来的偏移量的历史汇合。像夏令时 这样的异样会导致特定时间段内的偏移量会随工夫变动,无论是过来曾经产生的还是 将来政客们发表打算的扭转。
所以,当你理解时最好还是应用时区。
很多地区的偏移量都会随工夫变动。比方,美国的夏令时 会导致约半年左右的工夫内都会再原来的根底上偏移一个小时,而后再下半年再调整回这一个小时的偏移量。时区的意义就是记录这些所有的会造成偏移的状况。
因而,没有联合日期计算的偏移量没有意义的。举个例子,法国工夫 (Europe/Paris),在一年的一小部分工夫内偏移量为 +01:00,而因为夏令时的缘故,大部分工夫(三月末到十月末)的偏移量都是 +02:00。
// 指定区域,结构工夫: 法国巴黎工夫的以后工夫,五月有 DST,偏移量 +2
LocalDateTime now = LocalDateTime.of(LocalDate.of(2020, 5, 31), LocalTime.now())
ZonedDateTime zonedDateTime = ZonedDateTime.of(now, ZoneId.of(“Europe/Paris”));
zonedDateTime.getOffset(); // +02:00
// 手动调整的二月份,此时没有 DST,偏移量是 +1
ZonedDateTime thirdMonth = zonedDateTime.minusMonths(3);
thirdMonth.getOffset(); // +01:00