1. 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