Java日期时间API系列21—–Jdk8中java.time包中的新的日期时间API类,xk-time时间转换,计算,格式化,解析的工具

  通过工作之余,对Java8中java.time包源码的不断学习,使用和总结,开发了xk-time,初步完成,欢迎试用和提出建议!

xk-time

xk-time is a datetime converter calculator and formatter tool set, based on java8 date and time API, thread safe, easy to use.

时间转换,计算,格式化,解析的工具,使用java8,线程安全,简单易用,多达20几种常用日期格式化模板。

0.为什么要开发这个工具?

原因1:常见的DateUtil,往往将时间转换,计算,格式化,解析等功能都放在同一个类中,导致类功能复杂,方法太多,查找不方便。

xk-time工具包,将上面功能按照时间转换,时间计算,时间格式化解析分成3个工具类:DateTimeConverterUtil,DateTimeCalculatorUtil,DateTimeFormatterUtil,每个类只做一个种功能,方便使用。

原因2:java8以前的Date API设计不太好,往往会有线程安全问题

使用java8api,Instant、LocalDate、LocalDateTime、LocalTime、ZonedDateTime等都是线程安全的类,而且增加了更丰富的方法,在此基础上开发相关工具类,线程安全,让使用更方便。

1.依赖

  
  com.github.xkzhangsan    
  xk-time       
  0.0.2    
    

2.日期转换 DateTimeConverterUtil

包含Date、LocalDate、LocalDateTime、LocalTime、Instant和ZonedDateTime的互相转换
注意,ZonedDateTime相关的转换,尤其是其他时间转ZonedDateTime,要注意时间和对应时区一致。

3.日期计算工具类 DateTimeCalculatorUtil

包括:
(1)获取时间属性方法,get* 比如getYear(Date date) 获取年部分。
(2)获取时间加操作方法,plus* 比如plusYears(Date date, long amountToAdd) 当前时间年增加amountToAdd值。
(3)获取时间减操作方法,minus* 比如minusYears(Date date, long amountToAdd) 当前时间年减少amountToAdd值。
(4)获取时间修改属性方法,with* 比如withYear(Date date, long newValue) 修改当前时间年值为newValue。
(5)获取比较2个时间方法,between* 比如betweenYears(Date startInclusive, Date endExclusive) 比较2个时间,获取年部分。
(6)其他常用方法,比如isLeapYear(Date date) 判断是否闰年。
(7)时区转换计算方法,transform*,比如transform(ZonedDateTime zonedDateTime, String zoneId)
(8)比较2个时间大小和相等方法,compare*,比如compare(Date date1, Date date2)

4.日期格式化和解析DateTimeFormatterUtil

包含常用日期格式如:
yyyy-MM-dd
HH:mm:ss
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd’T’HH:mm:ssZ等等

注意:格式化和解析ZonedDateTime 时区时间时,只能使用ISO开头 的Formatter,如ISO_DATE_FMT和YYYY_MM_DD_T_HH_MM_SS_Z_FMT
因为,其他Formatter都绑定的是系统默认时区: private static final ZoneId ZONE = ZoneId.systemDefault();

如果需要使用其他Formatter,可以使用withZone方法重新设置时区,比如:
YYYY_MM_DD_HH_MM_SS_SSS_FMT.withZone(ZoneId.of(“Europe/Paris”)

 

源码地址:https://github.com/xkzhangsan/xk-time

Java日期时间API系列13—–Jdk8中java.time包中的新的日期时间API类,时间类转换,Date转LocalDateTime,LocalDateTime转Date等

  从前面的系列博客中可以看出Jdk8中java.time包中的新的日期时间API类设计的很好,但Date由于使用仍非常广泛,这就涉及到Date转LocalDateTime,LocalDateTime转Date。下面是时间类互相转换大全,包含Instant、LocalDate、LocalDateTime、LocalTime、ZonedDateTime和Date的相互转换,时间转换大全,下面是一个工具类,仅供参考:

具体包含:

LocalDateTime转Date,LocalDate转Date,LocalTime转Date,Instant转Date,epochMilli毫秒转Date,ZonedDateTime转Date,Date转LocalDateTime,LocalDate转LocalDateTime,LocalTime转LocalDateTime,Instant转LocalDateTime,epochMilli毫秒转LocalDateTime,temporal转LocalDateTime,ZonedDateTime转LocalDateTime,Date转LocalDate,LocalDateTime转LocalDate,Instant转LocalDate,temporal转LocalDate,ZonedDateTime转LocalDate,Date转LocalTime,LocalDateTime转LocalTime,Instant转LocalTime,temporal转LocalTime,ZonedDateTime转LocalTime,Date转Instant,LocalDateTime转Instant,LocalDate转Instant,LocalTime转Instant,epochMilli毫秒转Instant,temporal转Instant,ZonedDateTime转Instant,Date转毫秒值,LocalDateTime转毫秒值,LocalDate转毫秒值,Instant转毫秒值,ZonedDateTime转毫秒值,Date转ZonedDateTime,LocalDateTime转ZonedDateTime,LocalDate转ZonedDateTime,LocalTime转ZonedDateTime,Instant转ZonedDateTime,epochMilli毫秒转ZonedDateTime,temporal转ZonedDateTime.

 

package com.xkzhangsan.time.converter;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.Objects;

/**
 * 日期转换
 * 包含Date、LocalDate、LocalDateTime、LocalTime、Instant和ZonedDateTime的互相转换
 * 
 * 注意,ZonedDateTime相关的转换,尤其是其他时间转ZonedDateTime,要注意时间和对应时区一致。
* @ClassName: DateTimeConverterUtil 
* @Description: DateTime Converter
* @author xkzhangsan
* @date 2019年12月1日
*
 */
public class DateTimeConverterUtil {
    
    private DateTimeConverterUtil(){
    }

    /**
     * LocalDateTime转Date
     * @param localDateTime
     * @return
     */
    public static Date toDate(LocalDateTime localDateTime) {
        Objects.requireNonNull(localDateTime, "localDateTime");
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * LocalDate转Date
     * @param localDate
     * @return
     */
    public static Date toDate(LocalDate localDate) {
        Objects.requireNonNull(localDate, "localDate");
        return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }
    
    /**
     * LocalTime转Date
     * 以当天的日期+LocalTime组成新的LocalDateTime转换为Date
     * @param localTime
     * @return
     */
    public static Date toDate(LocalTime localTime) {
        Objects.requireNonNull(localTime, "localTime");
        return Date.from(LocalDate.now().atTime(localTime).atZone(ZoneId.systemDefault()).toInstant());
    }    

    /**
     * Instant转Date
     * @param instant
     * @return
     */
    public static Date toDate(Instant instant) {
        return Date.from(instant);
    }
    
    /**
     * epochMilli毫秒转Date
     * @param epochMilli
     * @return
     */
    public static Date toDate(long epochMilli){
        Objects.requireNonNull(epochMilli, "epochMilli");
        return new Date(epochMilli);
    }
    
    /**
     * ZonedDateTime转Date
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static Date toDate(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return Date.from(zonedDateTime.toInstant());
    }

    /**
     * Date转LocalDateTime
     * @param date
     * @return
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        Objects.requireNonNull(date, "date");
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * LocalDate转LocalDateTime
     * @param localDate
     * @return
     */
    public static LocalDateTime toLocalDateTime(LocalDate localDate) {
        Objects.requireNonNull(localDate, "localDate");
        return localDate.atStartOfDay();
    }
    
    /**
     * LocalTime转LocalDateTime
     * 以当天的日期+LocalTime组成新的LocalDateTime
     * @param localTime
     * @return
     */
    public static LocalDateTime toLocalDateTime(LocalTime localTime) {
        Objects.requireNonNull(localTime, "localTime");
        return LocalDate.now().atTime(localTime);
    }

    /**
     * Instant转LocalDateTime
     * @param instant
     * @return
     */
    public static LocalDateTime toLocalDateTime(Instant instant) {
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }
    
    /**
     * epochMilli毫秒转LocalDateTime
     * @param epochMilli
     * @return
     */
    public static LocalDateTime toLocalDateTime(long epochMilli) {
        Objects.requireNonNull(epochMilli, "epochMilli");
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneId.systemDefault());
    }
    
    /**
     * temporal转LocalDateTime
     * @param temporal
     * @return
     */
    public static LocalDateTime toLocalDateTime(TemporalAccessor temporal) {
        return LocalDateTime.from(temporal);
    }
    
    /**
     * ZonedDateTime转LocalDateTime
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static LocalDateTime toLocalDateTime(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toLocalDateTime();
    }

    /**
     * Date转LocalDate
     * @param date
     * @return
     */
    public static LocalDate toLocalDate(Date date) {
        return toLocalDateTime(date).toLocalDate();
    }

    /**
     * LocalDateTime转LocalDate
     * @param localDateTime
     * @return
     */
    public static LocalDate toLocalDate(LocalDateTime localDateTime) {
        Objects.requireNonNull(localDateTime, "localDateTime");
        return localDateTime.toLocalDate();
    }

    /**
     * Instant转LocalDate
     * @param instant
     * @return
     */
    public static LocalDate toLocalDate(Instant instant) {
        return toLocalDateTime(instant).toLocalDate();
    }
    
    /**
     * temporal转LocalDate
     * @param temporal
     * @return
     */
    public static LocalDate toLocalDate(TemporalAccessor temporal) {
        return LocalDate.from(temporal);
    }
    
    /**
     * ZonedDateTime转LocalDate
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static LocalDate toLocalDate(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toLocalDate();
    }

    /**
     * Date转LocalTime
     * @param date
     * @return
     */
    public static LocalTime toLocalTime(Date date) {
        return toLocalDateTime(date).toLocalTime();
    }

    /**
     * LocalDateTime转LocalTime
     * @param localDateTime
     * @return
     */
    public static LocalTime toLocalTime(LocalDateTime localDateTime) {
        Objects.requireNonNull(localDateTime, "localDateTime");
        return localDateTime.toLocalTime();
    }

    /**
     * Instant转LocalTime
     * @param instant
     * @return
     */
    public static LocalTime toLocalTime(Instant instant) {
        return toLocalDateTime(instant).toLocalTime();
    }
    
    /**
     * temporal转LocalTime
     * @param temporal
     * @return
     */
    public static LocalTime toLocalTime(TemporalAccessor temporal) {
        return LocalTime.from(temporal);
    }
    
    /**
     * ZonedDateTime转LocalTime
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static LocalTime toLocalTime(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toLocalTime();
    }

    /**
     * Date转Instant
     * @param date
     * @return
     */
    public static Instant toInstant(Date date) {
        Objects.requireNonNull(date, "date");
        return date.toInstant();
    }

    /**
     * LocalDateTime转Instant
     * @param localDateTime
     * @return
     */
    public static Instant toInstant(LocalDateTime localDateTime) {
        Objects.requireNonNull(localDateTime, "localDateTime");
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * LocalDate转Instant
     * @param localDate
     * @return
     */
    public static Instant toInstant(LocalDate localDate) {
        return toLocalDateTime(localDate).atZone(ZoneId.systemDefault()).toInstant();
    }
    
    /**
     * LocalTime转Instant
     * 以当天的日期+LocalTime组成新的LocalDateTime转换为Instant
     * @param localTime
     * @return
     */
    public static Instant toInstant(LocalTime localTime) {
        return toLocalDateTime(localTime).atZone(ZoneId.systemDefault()).toInstant();
    }
    
    /**
     * epochMilli毫秒转Instant
     * @param epochMilli
     * @return
     */
    public static Instant toInstant(long epochMilli) {
        Objects.requireNonNull(epochMilli, "epochMilli");
        return Instant.ofEpochMilli(epochMilli);
    }
    
    /**
     * temporal转Instant
     * @param temporal
     * @return
     */
    public static Instant toInstant(TemporalAccessor temporal) {
        return Instant.from(temporal);
    }
    
    /**
     * ZonedDateTime转Instant
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static Instant toInstant(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toInstant();
    }
    
    /**
     * Date转毫秒值
     * 从1970-01-01T00:00:00Z开始的毫秒值
     * @param date
     * @return
     */
    public static long toEpochMilli(Date date){
        Objects.requireNonNull(date, "date");
        return date.getTime();
    }
    
    /**
     * LocalDateTime转毫秒值
     * 从1970-01-01T00:00:00Z开始的毫秒值
     * @param localDateTime
     * @return
     */
    public static long toEpochMilli(LocalDateTime localDateTime){
        return toInstant(localDateTime).toEpochMilli();
    }
    
    /**
     * LocalDate转毫秒值
     * 从1970-01-01T00:00:00Z开始的毫秒值
     * @param localDate
     * @return
     */
    public static long toEpochMilli(LocalDate localDate){
        return toInstant(localDate).toEpochMilli();
    }
    
    /**
     * Instant转毫秒值
     * 从1970-01-01T00:00:00Z开始的毫秒值
     * @param instant
     * @return
     */
    public static long toEpochMilli(Instant instant){
        Objects.requireNonNull(instant, "instant");
        return instant.toEpochMilli();
    }
    
    /**
     * ZonedDateTime转毫秒值,注意时间对应的时区和默认时区差异
     * 从1970-01-01T00:00:00Z开始的毫秒值
     * @param zonedDateTime
     * @return
     */
    public static long toEpochMilli(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toInstant().toEpochMilli();
    }
    
    /**
     * Date转ZonedDateTime,时区为系统默认时区
     * @param date
     * @return
     */
    public static ZonedDateTime toZonedDateTime(Date date) {
        Objects.requireNonNull(date, "date");
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime()
                .atZone(ZoneId.systemDefault());
    }
    
    /**
     * LocalDateTime转ZonedDateTime,时区为系统默认时区
     * @param localDateTime
     * @return
     */
    public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime) {
        Objects.requireNonNull(localDateTime, "localDateTime");
        return localDateTime.atZone(ZoneId.systemDefault());
    }

/**
* LocalDateTime转ZonedDateTime,时区为zoneId对应时区
* 注意,需要保证localDateTime和zoneId是对应的,不然会出现错误
*
* @param localDateTime
* @param zoneId
* @return
*/
public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime, String zoneId) {
  Objects.requireNonNull(localDateTime, “localDateTime”);
  Objects.requireNonNull(zoneId, “zoneId”);
  return localDateTime.atZone(ZoneId.of(zoneId));
}

/**
     * LocalDate转ZonedDateTime,时区为系统默认时区
     * @param localDate
     * @return such as 2020-02-19T00:00+08:00[Asia/Shanghai]
     */
    public static ZonedDateTime toZonedDateTime(LocalDate localDate) {
        Objects.requireNonNull(localDate, "localDate");
        return localDate.atStartOfDay().atZone(ZoneId.systemDefault());
    }
    
    /**
     * LocalTime转ZonedDateTime
     * 以当天的日期+LocalTime组成新的ZonedDateTime,时区为系统默认时区
     * @param localTime
     * @return
     */
    public static ZonedDateTime toZonedDateTime(LocalTime localTime) {
        Objects.requireNonNull(localTime, "localTime");
        return LocalDate.now().atTime(localTime).atZone(ZoneId.systemDefault());
    }

    /**
     * Instant转ZonedDateTime,时区为系统默认时区
     * @param instant
     * @return
     */
    public static ZonedDateTime toZonedDateTime(Instant instant) {
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).atZone(ZoneId.systemDefault());
    }
    
    /**
     * epochMilli毫秒转ZonedDateTime,时区为系统默认时区
     * @param epochMilli
     * @return
     */
    public static ZonedDateTime toZonedDateTime(long epochMilli) {
        Objects.requireNonNull(epochMilli, "epochMilli");
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneId.systemDefault())
                .atZone(ZoneId.systemDefault());
    }
    
    /**
     * temporal转ZonedDateTime,时区为系统默认时区
     * @param temporal
     * @return
     */
    public static ZonedDateTime toZonedDateTime(TemporalAccessor temporal) {
        return LocalDateTime.from(temporal).atZone(ZoneId.systemDefault());
    }    

}

 

 测试代码

package com.xkzhangsan.time.test;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.Date;

import org.junit.Test;

import com.xkzhangsan.time.converter.DateTimeConverterUtil;

public class ConverterTest {
    
    @Test
    public void dateConverterTest(){
        System.out.println("===================dateConverterTest=====================");
        Date date = new Date();
        System.out.println(DateTimeConverterUtil.toLocalDateTime(date));
        System.out.println(DateTimeConverterUtil.toLocalDate(date));
        System.out.println(DateTimeConverterUtil.toLocalTime(date));
        System.out.println(DateTimeConverterUtil.toInstant(date));
    }
    
    @Test
    public void localDateTimeConverterTest(){
        System.out.println("===================localDateTimeConverterTest=====================");
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);
        System.out.println(DateTimeConverterUtil.toDate(ldt));
        System.out.println(DateTimeConverterUtil.toLocalDate(ldt));
        System.out.println(DateTimeConverterUtil.toLocalTime(ldt));
        System.out.println(DateTimeConverterUtil.toInstant(ldt));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(ldt));
    }
    
    @Test
    public void localDateConverterTest(){
        System.out.println("===================localDateConverterTest=====================");
        LocalDate ld = LocalDate.now();
        System.out.println(ld);
        System.out.println(DateTimeConverterUtil.toDate(ld));
        System.out.println(DateTimeConverterUtil.toLocalDateTime(ld));
        System.out.println(DateTimeConverterUtil.toInstant(ld));
    }
    
    @Test
    public void localTimeConverterTest(){
        System.out.println("===================localTimeConverterTest=====================");
        LocalTime lt = LocalTime.now();
        System.out.println(lt);
        System.out.println(DateTimeConverterUtil.toDate(lt));
        System.out.println(DateTimeConverterUtil.toLocalDateTime(lt));
        System.out.println(DateTimeConverterUtil.toLocalTime(lt));
        System.out.println(DateTimeConverterUtil.toInstant(lt));
    }    

    
    @Test
    public void instantConverterTest(){
        System.out.println("===================instantConverterTest=====================");
        Instant instant = Instant.now();
        System.out.println(instant);
        System.out.println(DateTimeConverterUtil.toDate(instant));
        System.out.println(DateTimeConverterUtil.toLocalDateTime(instant));
        System.out.println(DateTimeConverterUtil.toLocalDate(instant));
    }
    
    @Test
    public void zonedDateTimeConverterTest(){
        System.out.println("===================zonedDateTimeConverterTest=====================");
        System.out.println("===================ToOther=====================");
        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        System.out.println(zonedDateTime);
        System.out.println(DateTimeConverterUtil.toDate(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toLocalDateTime(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toLocalDate(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toLocalTime(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toInstant(zonedDateTime));
        System.out.println("===================toZonedDateTime=====================");
        System.out.println(zonedDateTime);
        System.out.println(DateTimeConverterUtil.toZonedDateTime(new Date()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(LocalDateTime.now()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(LocalDate.now()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(LocalTime.now()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(Instant.now()));
    }    
}

 

输出:

===================dateConverterTest=====================
2020-02-19T16:10:04.366
2020-02-19
16:10:04.366
2020-02-19T08:10:04.366Z
===================localTimeConverterTest=====================
16:10:04.458
Wed Feb 19 16:10:04 CST 2020
2020-02-19T16:10:04.458
16:10:04.458
2020-02-19T08:10:04.458Z
===================localDateConverterTest=====================
2020-02-19
Wed Feb 19 00:00:00 CST 2020
2020-02-19T00:00
2020-02-18T16:00:00Z
===================zonedDateTimeConverterTest=====================
===================ToOther=====================
2020-02-19T16:10:04.464+08:00[Asia/Shanghai]
Wed Feb 19 16:10:04 CST 2020
2020-02-19T16:10:04.464
2020-02-19
16:10:04.464
2020-02-19T08:10:04.464Z
===================toZonedDateTime=====================
2020-02-19T16:10:04.464+08:00[Asia/Shanghai]
2020-02-19T16:10:04.465+08:00[Asia/Shanghai]
2020-02-19T16:10:04.465+08:00[Asia/Shanghai]
2020-02-19T00:00+08:00[Asia/Shanghai]
2020-02-19T16:10:04.466+08:00[Asia/Shanghai]
2020-02-19T16:10:04.466+08:00[Asia/Shanghai]
===================localDateTimeConverterTest=====================
2020-02-19T16:10:04.466
Wed Feb 19 16:10:04 CST 2020
2020-02-19
16:10:04.466
2020-02-19T08:10:04.466Z
2020-02-19T16:10:04.466+08:00[Asia/Shanghai]
===================instantConverterTest=====================
2020-02-19T08:10:04.467Z
Wed Feb 19 16:10:04 CST 2020
2020-02-19T16:10:04.467
2020-02-19

 

源码地址:https://github.com/xkzhangsan/xk-time

Java日期时间API系列20—–Jdk8中java.time包中的新的日期时间API类,ZoneId时区ID大全等。

  Java日期时间API系列19—–Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格式化和时区转换等。中已经对ZoneId说明,并列出了常用时区ID信息。

  并且通过 java.time.ZoneId.getAvailableZoneIds()获取到所有可用时区ID。

1.测试代码

    /**
     * 获取可用时区ID
     */
    @Test
    public void getAvailableZoneIds(){
        for(String zoneId : ZoneId.getAvailableZoneIds()){
            System.out.println(zoneId);
        }
    }

 

输出:

Asia/Aden
America/Cuiaba
Etc/GMT+9
Etc/GMT+8
Africa/Nairobi
America/Marigot
Asia/Aqtau
Pacific/Kwajalein
America/El_Salvador
Asia/Pontianak
Africa/Cairo
Pacific/Pago_Pago
Africa/Mbabane
Asia/Kuching
Pacific/Honolulu
Pacific/Rarotonga
America/Guatemala
Australia/Hobart
Europe/London
America/Belize
America/Panama
Asia/Chungking
America/Managua
America/Indiana/Petersburg
Asia/Yerevan
Europe/Brussels
GMT
Europe/Warsaw
America/Chicago
Asia/Kashgar
Chile/Continental
Pacific/Yap
CET
Etc/GMT-1
Etc/GMT-0
Europe/Jersey
America/Tegucigalpa
Etc/GMT-5
Europe/Istanbul
America/Eirunepe
Etc/GMT-4
America/Miquelon
Etc/GMT-3
Europe/Luxembourg
Etc/GMT-2
Etc/GMT-9
America/Argentina/Catamarca
Etc/GMT-8
Etc/GMT-7
Etc/GMT-6
Europe/Zaporozhye
Canada/Yukon
Canada/Atlantic
Atlantic/St_Helena
Australia/Tasmania
Libya
Europe/Guernsey
America/Grand_Turk
US/Pacific-New
Asia/Samarkand
America/Argentina/Cordoba
Asia/Phnom_Penh
Africa/Kigali
Asia/Almaty
US/Alaska
Asia/Dubai
Europe/Isle_of_Man
America/Araguaina
Cuba
Asia/Novosibirsk
America/Argentina/Salta
Etc/GMT+3
Africa/Tunis
Etc/GMT+2
Etc/GMT+1
Pacific/Fakaofo
Africa/Tripoli
Etc/GMT+0
Israel
Africa/Banjul
Etc/GMT+7
Indian/Comoro
Etc/GMT+6
Etc/GMT+5
Etc/GMT+4
Pacific/Port_Moresby
US/Arizona
Antarctica/Syowa
Indian/Reunion
Pacific/Palau
Europe/Kaliningrad
America/Montevideo
Africa/Windhoek
Asia/Karachi
Africa/Mogadishu
Australia/Perth
Brazil/East
Etc/GMT
Asia/Chita
Pacific/Easter
Antarctica/Davis
Antarctica/McMurdo
Asia/Macao
America/Manaus
Africa/Freetown
Europe/Bucharest
Asia/Tomsk
America/Argentina/Mendoza
Asia/Macau
Europe/Malta
Mexico/BajaSur
Pacific/Tahiti
Africa/Asmera
Europe/Busingen
America/Argentina/Rio_Gallegos
Africa/Malabo
Europe/Skopje
America/Catamarca
America/Godthab
Europe/Sarajevo
Australia/ACT
GB-Eire
Africa/Lagos
America/Cordoba
Europe/Rome
Asia/Dacca
Indian/Mauritius
Pacific/Samoa
America/Regina
America/Fort_Wayne
America/Dawson_Creek
Africa/Algiers
Europe/Mariehamn
America/St_Johns
America/St_Thomas
Europe/Zurich
America/Anguilla
Asia/Dili
America/Denver
Africa/Bamako
Europe/Saratov
GB
Mexico/General
Pacific/Wallis
Europe/Gibraltar
Africa/Conakry
Africa/Lubumbashi
Asia/Istanbul
America/Havana
NZ-CHAT
Asia/Choibalsan
America/Porto_Acre
Asia/Omsk
Europe/Vaduz
US/Michigan
Asia/Dhaka
America/Barbados
Europe/Tiraspol
Atlantic/Cape_Verde
Asia/Yekaterinburg
America/Louisville
Pacific/Johnston
Pacific/Chatham
Europe/Ljubljana
America/Sao_Paulo
Asia/Jayapura
America/Curacao
Asia/Dushanbe
America/Guyana
America/Guayaquil
America/Martinique
Portugal
Europe/Berlin
Europe/Moscow
Europe/Chisinau
America/Puerto_Rico
America/Rankin_Inlet
Pacific/Ponape
Europe/Stockholm
Europe/Budapest
America/Argentina/Jujuy
Australia/Eucla
Asia/Shanghai
Universal
Europe/Zagreb
America/Port_of_Spain
Europe/Helsinki
Asia/Beirut
Asia/Tel_Aviv
Pacific/Bougainville
US/Central
Africa/Sao_Tome
Indian/Chagos
America/Cayenne
Asia/Yakutsk
Pacific/Galapagos
Australia/North
Europe/Paris
Africa/Ndjamena
Pacific/Fiji
America/Rainy_River
Indian/Maldives
Australia/Yancowinna
SystemV/AST4
Asia/Oral
America/Yellowknife
Pacific/Enderbury
America/Juneau
Australia/Victoria
America/Indiana/Vevay
Asia/Tashkent
Asia/Jakarta
Africa/Ceuta
Asia/Barnaul
America/Recife
America/Buenos_Aires
America/Noronha
America/Swift_Current
Australia/Adelaide
America/Metlakatla
Africa/Djibouti
America/Paramaribo
Europe/Simferopol
Europe/Sofia
Africa/Nouakchott
Europe/Prague
America/Indiana/Vincennes
Antarctica/Mawson
America/Kralendijk
Antarctica/Troll
Europe/Samara
Indian/Christmas
America/Antigua
Pacific/Gambier
America/Indianapolis
America/Inuvik
America/Iqaluit
Pacific/Funafuti
UTC
Antarctica/Macquarie
Canada/Pacific
America/Moncton
Africa/Gaborone
Pacific/Chuuk
Asia/Pyongyang
America/St_Vincent
Asia/Gaza
Etc/Universal
PST8PDT
Atlantic/Faeroe
Asia/Qyzylorda
Canada/Newfoundland
America/Kentucky/Louisville
America/Yakutat
Asia/Ho_Chi_Minh
Antarctica/Casey
Europe/Copenhagen
Africa/Asmara
Atlantic/Azores
Europe/Vienna
ROK
Pacific/Pitcairn
America/Mazatlan
Australia/Queensland
Pacific/Nauru
Europe/Tirane
Asia/Kolkata
SystemV/MST7
Australia/Canberra
MET
Australia/Broken_Hill
Europe/Riga
America/Dominica
Africa/Abidjan
America/Mendoza
America/Santarem
Kwajalein
America/Asuncion
Asia/Ulan_Bator
NZ
America/Boise
Australia/Currie
EST5EDT
Pacific/Guam
Pacific/Wake
Atlantic/Bermuda
America/Costa_Rica
America/Dawson
Asia/Chongqing
Eire
Europe/Amsterdam
America/Indiana/Knox
America/North_Dakota/Beulah
Africa/Accra
Atlantic/Faroe
Mexico/BajaNorte
America/Maceio
Etc/UCT
Pacific/Apia
GMT0
America/Atka
Pacific/Niue
Australia/Lord_Howe
Europe/Dublin
Pacific/Truk
MST7MDT
America/Monterrey
America/Nassau
America/Jamaica
Asia/Bishkek
America/Atikokan
Atlantic/Stanley
Australia/NSW
US/Hawaii
SystemV/CST6
Indian/Mahe
Asia/Aqtobe
America/Sitka
Asia/Vladivostok
Africa/Libreville
Africa/Maputo
Zulu
America/Kentucky/Monticello
Africa/El_Aaiun
Africa/Ouagadougou
America/Coral_Harbour
Pacific/Marquesas
Brazil/West
America/Aruba
America/North_Dakota/Center
America/Cayman
Asia/Ulaanbaatar
Asia/Baghdad
Europe/San_Marino
America/Indiana/Tell_City
America/Tijuana
Pacific/Saipan
SystemV/YST9
Africa/Douala
America/Chihuahua
America/Ojinaga
Asia/Hovd
America/Anchorage
Chile/EasterIsland
America/Halifax
Antarctica/Rothera
America/Indiana/Indianapolis
US/Mountain
Asia/Damascus
America/Argentina/San_Luis
America/Santiago
Asia/Baku
America/Argentina/Ushuaia
Atlantic/Reykjavik
Africa/Brazzaville
Africa/Porto-Novo
America/La_Paz
Antarctica/DumontDUrville
Asia/Taipei
Antarctica/South_Pole
Asia/Manila
Asia/Bangkok
Africa/Dar_es_Salaam
Poland
Atlantic/Madeira
Antarctica/Palmer
America/Thunder_Bay
Africa/Addis_Ababa
Asia/Yangon
Europe/Uzhgorod
Brazil/DeNoronha
Asia/Ashkhabad
Etc/Zulu
America/Indiana/Marengo
America/Creston
America/Punta_Arenas
America/Mexico_City
Antarctica/Vostok
Asia/Jerusalem
Europe/Andorra
US/Samoa
PRC
Asia/Vientiane
Pacific/Kiritimati
America/Matamoros
America/Blanc-Sablon
Asia/Riyadh
Iceland
Pacific/Pohnpei
Asia/Ujung_Pandang
Atlantic/South_Georgia
Europe/Lisbon
Asia/Harbin
Europe/Oslo
Asia/Novokuznetsk
CST6CDT
Atlantic/Canary
America/Knox_IN
Asia/Kuwait
SystemV/HST10
Pacific/Efate
Africa/Lome
America/Bogota
America/Menominee
America/Adak
Pacific/Norfolk
Europe/Kirov
America/Resolute
Pacific/Tarawa
Africa/Kampala
Asia/Krasnoyarsk
Greenwich
SystemV/EST5
America/Edmonton
Europe/Podgorica
Australia/South
Canada/Central
Africa/Bujumbura
America/Santo_Domingo
US/Eastern
Europe/Minsk
Pacific/Auckland
Africa/Casablanca
America/Glace_Bay
Canada/Eastern
Asia/Qatar
Europe/Kiev
Singapore
Asia/Magadan
SystemV/PST8
America/Port-au-Prince
Europe/Belfast
America/St_Barthelemy
Asia/Ashgabat
Africa/Luanda
America/Nipigon
Atlantic/Jan_Mayen
Brazil/Acre
Asia/Muscat
Asia/Bahrain
Europe/Vilnius
America/Fortaleza
Etc/GMT0
US/East-Indiana
America/Hermosillo
America/Cancun
Africa/Maseru
Pacific/Kosrae
Africa/Kinshasa
Asia/Kathmandu
Asia/Seoul
Australia/Sydney
America/Lima
Australia/LHI
America/St_Lucia
Europe/Madrid
America/Bahia_Banderas
America/Montserrat
Asia/Brunei
America/Santa_Isabel
Canada/Mountain
America/Cambridge_Bay
Asia/Colombo
Australia/West
Indian/Antananarivo
Australia/Brisbane
Indian/Mayotte
US/Indiana-Starke
Asia/Urumqi
US/Aleutian
Europe/Volgograd
America/Lower_Princes
America/Vancouver
Africa/Blantyre
America/Rio_Branco
America/Danmarkshavn
America/Detroit
America/Thule
Africa/Lusaka
Asia/Hong_Kong
Iran
America/Argentina/La_Rioja
Africa/Dakar
SystemV/CST6CDT
America/Tortola
America/Porto_Velho
Asia/Sakhalin
Etc/GMT+10
America/Scoresbysund
Asia/Kamchatka
Asia/Thimbu
Africa/Harare
Etc/GMT+12
Etc/GMT+11
Navajo
America/Nome
Europe/Tallinn
Turkey
Africa/Khartoum
Africa/Johannesburg
Africa/Bangui
Europe/Belgrade
Jamaica
Africa/Bissau
Asia/Tehran
WET
Europe/Astrakhan
Africa/Juba
America/Campo_Grande
America/Belem
Etc/Greenwich
Asia/Saigon
America/Ensenada
Pacific/Midway
America/Jujuy
Africa/Timbuktu
America/Bahia
America/Goose_Bay
America/Virgin
America/Pangnirtung
Asia/Katmandu
America/Phoenix
Africa/Niamey
America/Whitehorse
Pacific/Noumea
Asia/Tbilisi
America/Montreal
Asia/Makassar
America/Argentina/San_Juan
Hongkong
UCT
Asia/Nicosia
America/Indiana/Winamac
SystemV/MST7MDT
America/Argentina/ComodRivadavia
America/Boa_Vista
America/Grenada
Asia/Atyrau
Australia/Darwin
Asia/Khandyga
Asia/Kuala_Lumpur
Asia/Famagusta
Asia/Thimphu
Asia/Rangoon
Europe/Bratislava
Asia/Calcutta
America/Argentina/Tucuman
Asia/Kabul
Indian/Cocos
Japan
Pacific/Tongatapu
America/New_York
Etc/GMT-12
Etc/GMT-11
Etc/GMT-10
SystemV/YST9YDT
Europe/Ulyanovsk
Etc/GMT-14
Etc/GMT-13
W-SU
America/Merida
EET
America/Rosario
Canada/Saskatchewan
America/St_Kitts
Arctic/Longyearbyen
America/Fort_Nelson
America/Caracas
America/Guadeloupe
Asia/Hebron
Indian/Kerguelen
SystemV/PST8PDT
Africa/Monrovia
Asia/Ust-Nera
Egypt
Asia/Srednekolymsk
America/North_Dakota/New_Salem
Asia/Anadyr
Australia/Melbourne
Asia/Irkutsk
America/Shiprock
America/Winnipeg
Europe/Vatican
Asia/Amman
Etc/UTC
SystemV/AST4ADT
Asia/Tokyo
America/Toronto
Asia/Singapore
Australia/Lindeman
America/Los_Angeles
SystemV/EST5EDT
Pacific/Majuro
America/Argentina/Buenos_Aires
Europe/Nicosia
Pacific/Guadalcanal
Europe/Athens
US/Pacific
Europe/Monaco

====================================================

可以通过Google 翻译得到上面时区ID的中文含义。

 

Java日期时间API系列19—–Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格式化和时区转换等。

  通过Java日期时间API系列6—–Jdk8中java.time包中的新的日期时间API类中时间范围示意图:可以很清晰的看出ZonedDateTime相当于LocalDateTime+ZoneId。

  

  ZonedDateTime是用来处理时区相关的时间,它的各种计算都离不开ZoneId。先看ZoneId。

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秒。

1.2  常用时区名称和缩写如下:

package com.xkzhangsan.time.enums;

/**
 * 常用时区枚举 包含中文名称,比如:"Asia/Shanghai","亚洲/上海"
 * 
 * @ClassName: ZoneIdEnum
 * @Description: ZoneIdEnum
 * @author xkzhangsan
 * @date 2020年02月18日
 * @version 0.1 ,初版,试用
 */
public enum ZoneIdEnum {

    /**
     * "Australia/Darwin","澳洲/达尔文"
     */
    ACT("Australia/Darwin", "澳洲/达尔文"),

    /**
     * "Australia/Sydney","澳洲/悉尼"
     */
    AET("Australia/Sydney", "澳洲/悉尼"),

    /**
     * "America/Argentina/Buenos_Aires","美洲/阿根廷/布宜诺斯艾利斯"
     */
    AGT("America/Argentina/Buenos_Aires", "美洲/阿根廷/布宜诺斯艾利斯"),

    /**
     * "Africa/Cairo","非洲/开罗"
     */
    ART("Africa/Cairo", "非洲/开罗"),

    /**
     * "America/Anchorage","美洲/安克雷奇"
     */
    AST("America/Anchorage", "美洲/安克雷奇"),

    /**
     * "America/Sao_Paulo","美洲/圣保罗"
     */
    BET("America/Sao_Paulo", "美洲/圣保罗"),

    /**
     * "Asia/Dhaka","亚洲/达卡"
     */
    BST("Asia/Dhaka", "亚洲/达卡"),

    /**
     * "Africa/Harare","非洲/哈拉雷"
     */
    CAT("Africa/Harare", "非洲/哈拉雷"),

    /**
     * "America/St_Johns","美洲/圣约翰"
     */
    CNT("America/St_Johns", "美洲/圣约翰"),

    /**
     * "America/Chicago","美洲/芝加哥"
     */
    CST("America/Chicago", "美洲/芝加哥"),

    /**
     * "Asia/Shanghai","亚洲/上海"
     */
    CTT("Asia/Shanghai", "亚洲/上海"),

    /**
     * "Africa/Addis_Ababa","非洲/亚的斯亚贝巴"
     */
    EAT("Africa/Addis_Ababa", "非洲/亚的斯亚贝巴"),

    /**
     * "Europe/Paris","欧洲/巴黎"
     */
    ECT("Europe/Paris", "欧洲/巴黎"),

    /**
     * "America/Indiana/Indianapolis","美洲/印第安纳州/印第安纳波利斯"
     */
    IET("America/Indiana/Indianapolis", "美洲/印第安纳州/印第安纳波利斯"),

    /**
     * "Asia/Kolkata","亚洲/加尔各答"
     */
    IST("Asia/Kolkata", "亚洲/加尔各答"),

    /**
     * "Asia/Tokyo","亚洲/东京"
     */
    JST("Asia/Tokyo", "亚洲/东京"),

    /**
     * "Pacific/Apia","太平洋/阿皮亚"
     */
    MIT("Pacific/Apia", "太平洋/阿皮亚"),

    /**
     * "Asia/Yerevan","亚洲/埃里温"
     */
    NET("Asia/Yerevan", "亚洲/埃里温"),

    /**
     * "Pacific/Auckland","太平洋/奥克兰"
     */
    NST("Pacific/Auckland", "太平洋/奥克兰"),

    /**
     * "Asia/Karachi","亚洲/卡拉奇"
     */
    PLT("Asia/Karachi", "亚洲/卡拉奇"),

    /**
     * "America/Phoenix","美洲/凤凰城"
     */
    PNT("America/Phoenix", "美洲/凤凰城"),

    /**
     * "America/Puerto_Rico","美洲/波多黎各"
     */
    PRT("America/Puerto_Rico", "美洲/波多黎各"),

    /**
     * "America/Los_Angeles","美洲/洛杉矶"
     */
    PST("America/Los_Angeles", "美洲/洛杉矶"),

    /**
     * "Pacific/Guadalcanal","太平洋/瓜达尔卡纳尔岛"
     */
    SST("Pacific/Guadalcanal", "太平洋/瓜达尔卡纳尔岛"),

    /**
     * "Asia/Ho_Chi_Minh","亚洲/胡志明市"
     */
    VST("Asia/Ho_Chi_Minh", "亚洲/胡志明市"),

    /**
     * "-05:00","东部标准时间"(纽约、华盛顿)
     */
    EST("-05:00", "东部标准时间"),

    /**
     * "-07:00","山地标准时间"
     */
    MST("-07:00", "山地标准时间"),

    /**
     * "-10:00","夏威夷-阿留申标准时区"
     */
    HST("-10:00", "夏威夷-阿留申标准时区"),;

    private final String zoneIdName;
    private final String zoneIdNameCn;

    public String getZoneIdName() {
        return zoneIdName;
    }

    public String getZoneIdNameCn() {
        return zoneIdNameCn;
    }

    private ZoneIdEnum(String zoneIdName, String zoneIdNameCn) {
        this.zoneIdName = zoneIdName;
        this.zoneIdNameCn = zoneIdNameCn;
    }
}

1.3  更多时区id

  可以通过 java.time.ZoneId.getAvailableZoneIds()获取到。

 

2. ZonedDateTime,ISO-8601日历系统中带有时区的日期时间,例如:2007-12-03T10:15:30+01:00 Europe/Paris

2.1 创建ZonedDateTime

        ZonedDateTime.now();

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

 

2.2 ZonedDateTime与其他时间类的转换

    /**
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static Date toDate(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return Date.from(zonedDateTime.toInstant());
    }
    
    /**
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static LocalDateTime toLocalDateTime(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toLocalDateTime();
    }
    
    /**
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static LocalDate toLocalDate(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toLocalDate();
    }
    
    /**
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static LocalTime toLocalTime(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toLocalTime();
    }
    
    /**
     * 注意时间对应的时区和默认时区差异
     * @param zonedDateTime
     * @return
     */
    public static Instant toInstant(ZonedDateTime zonedDateTime) {
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        return zonedDateTime.toInstant();
    }

    /**
     * 转换为ZonedDateTime,时区为系统默认时区
     * @param date
     * @return
     */
    public static ZonedDateTime toZonedDateTime(Date date) {
        Objects.requireNonNull(date, "date");
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime()
                .atZone(ZoneId.systemDefault());
    }
    
    /**
     * 转换为ZonedDateTime,时区为系统默认时区
     * @param localDateTime
     * @return
     */
    public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime) {
        Objects.requireNonNull(localDateTime, "localDateTime");
        return localDateTime.atZone(ZoneId.systemDefault());
    }
/** * LocalDateTime转ZonedDateTime,时区为zoneId对应时区 * 注意,需要保证localDateTime和zoneId是对应的,不然会出现错误 * * @param localDateTime * @param zoneId * @return */ public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime, String zoneId) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(zoneId, "zoneId"); return localDateTime.atZone(ZoneId.of(zoneId)); }
/** * 转换为ZonedDateTime,时区为系统默认时区 * @param localDate * @return */ public static ZonedDateTime toZonedDateTime(LocalDate localDate) { Objects.requireNonNull(localDate, "localDate"); return localDate.atStartOfDay().atZone(ZoneId.systemDefault()); } /** * 以当天的日期+LocalTime组成新的ZonedDateTime,时区为系统默认时区 * @param localTime * @return */ public static ZonedDateTime toZonedDateTime(LocalTime localTime) { Objects.requireNonNull(localTime, "localTime"); return LocalDate.now().atTime(localTime).atZone(ZoneId.systemDefault()); } /** * 转换为ZonedDateTime,时区为系统默认时区 * @param instant * @return */ public static ZonedDateTime toZonedDateTime(Instant instant) { return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).atZone(ZoneId.systemDefault()); }

===================================================================================

测试代码:

    @Test
    public void zonedDateTimeConverterTest(){
        System.out.println("===================zonedDateTimeConverterTest=====================");
        System.out.println("===================ToOther=====================");
        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        System.out.println(zonedDateTime);
        System.out.println(DateTimeConverterUtil.toDate(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toLocalDateTime(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toLocalDate(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toLocalTime(zonedDateTime));
        System.out.println(DateTimeConverterUtil.toInstant(zonedDateTime));
        System.out.println("===================toZonedDateTime=====================");
        System.out.println(zonedDateTime);
        System.out.println(DateTimeConverterUtil.toZonedDateTime(new Date()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(LocalDateTime.now()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(LocalDate.now()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(LocalTime.now()));
        System.out.println(DateTimeConverterUtil.toZonedDateTime(Instant.now()));
    }

 

输出:

===================zonedDateTimeConverterTest=====================
===================ToOther=====================
2020-02-19T13:33:03.130+08:00[Asia/Shanghai]
Wed Feb 19 13:33:03 CST 2020
2020-02-19T13:33:03.130
2020-02-19
13:33:03.130
2020-02-19T05:33:03.130Z
===================toZonedDateTime=====================
2020-02-19T13:33:03.130+08:00[Asia/Shanghai]
2020-02-19T13:33:03.150+08:00[Asia/Shanghai]
2020-02-19T13:33:03.150+08:00[Asia/Shanghai]
2020-02-19T00:00+08:00[Asia/Shanghai]
2020-02-19T13:33:03.150+08:00[Asia/Shanghai]
2020-02-19T13:33:03.150+08:00[Asia/Shanghai]

由于  public static ZonedDateTime toZonedDateTime(LocalDate localDate),LocalDate只包含日期,所以,转换后显示为:2020-02-19T00:00+08:00[Asia/Shanghai]

 

2.3 常用时区时间创建和时区转换计算

常用时间,如北京时间,巴黎时间,纽约时间,东京时间等。

    /**
     * 获取当前系统当前时区时间
     * @param zoneId
     * @return
     */
    public static ZonedDateTime getZonedDateTimeNowOfDefault(){
        return ZonedDateTime.now(ZoneId.systemDefault());
    }
    
    /**
     * 获取当前上海时区时间(北京时间)
     * @param zoneId
     * @return
     */
    public static ZonedDateTime getZonedDateTimeNowOfShanghai(){
        return ZonedDateTime.now(ZoneId.of(ZoneIdEnum.CTT.getZoneIdName()));
    }
    
    /**
     * 获取当前巴黎时区时间
     * @param zoneId
     * @return
     */
    public static ZonedDateTime getZonedDateTimeNowOfParis(){
        return ZonedDateTime.now(ZoneId.of(ZoneIdEnum.ECT.getZoneIdName()));
    }
    
    /**
     * 获取当前美国东部标准时区(纽约、华盛顿)
     * @param zoneId
     * @return
     */
    public static ZonedDateTime getZonedDateTimeNowOfEST(){
        return ZonedDateTime.now(ZoneId.of(ZoneIdEnum.EST.getZoneIdName()));
    }
    
    /**
     * 获取当前东京时区时间
     * @param zoneId
     * @return
     */
    public static ZonedDateTime getZonedDateTimeNowOfTokyo(){
        return ZonedDateTime.now(ZoneId.of(ZoneIdEnum.JST.getZoneIdName()));
    }    
    
    /**
     * 获取时区当前时间
     * @param zoneId
     * @return
     */
    public static ZonedDateTime getZonedDateTimeNow(String zoneId){
        Objects.requireNonNull(zoneId, "zoneId");
        return ZonedDateTime.now(ZoneId.of(zoneId));
    }
    
    /**
     * 时区转换计算
     * @param zonedDateTime
     * @param zoneId 例如 Asia/Shanghai
     * @return
     */
    public static ZonedDateTime transform(ZonedDateTime zonedDateTime, String zoneId){
        Objects.requireNonNull(zoneId, "zoneId");
        return transform(zonedDateTime, ZoneId.of(zoneId));
    }
    
    /**
     * 时区转换计算
     * @param zonedDateTime
     * @param zone
     * @return
     */
    public static ZonedDateTime transform(ZonedDateTime zonedDateTime, ZoneId zone){
        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
        Objects.requireNonNull(zone, "zone");
        return zonedDateTime.withZoneSameInstant(zone);
    }

 

测试代码:

    /**
     * 时区时间计算
     */
    @Test
    public void zonedDateTimeTest(){
        //系统默认时区
        System.out.println(DateTimeCalculatorUtil.getZonedDateTimeNowOfDefault());
        //系统上海时区
        ZonedDateTime shanghaiZonedDateTime = DateTimeCalculatorUtil.getZonedDateTimeNowOfShanghai();
        System.out.println(shanghaiZonedDateTime);
        //系统巴黎时区
        ZonedDateTime parisZonedDateTime = DateTimeCalculatorUtil.getZonedDateTimeNowOfParis();
        System.out.println(parisZonedDateTime);
        //系统美国东部时区纽约时间
        System.out.println(DateTimeCalculatorUtil.getZonedDateTimeNowOfEST());
        //系统东京时区
        System.out.println(DateTimeCalculatorUtil.getZonedDateTimeNowOfTokyo());
        
        //上海时区,转换为巴黎时区
        System.out.println("============transform 时区转换=============");
        System.out.println("shanghaiZonedDateTime: "+shanghaiZonedDateTime);
        ZonedDateTime transformZonedDateTime = DateTimeCalculatorUtil.transform(shanghaiZonedDateTime,
                ZoneIdEnum.ECT.getZoneIdName());
        System.out.println("transformZonedDateTime: "+transformZonedDateTime);
        
    }

 

输出:

2020-02-19T13:40:49.638+08:00[Asia/Shanghai]
2020-02-19T13:40:49.640+08:00[Asia/Shanghai]
2020-02-19T06:40:49.642+01:00[Europe/Paris]
2020-02-19T00:40:49.653-05:00
2020-02-19T14:40:49.653+09:00[Asia/Tokyo]
============transform 时区转换=============
shanghaiZonedDateTime: 2020-02-19T13:40:49.640+08:00[Asia/Shanghai]
transformZonedDateTime: 2020-02-19T06:40:49.640+01:00[Europe/Paris]

 

2.4 时区时间格式化与解析

(1)时区时间格式化和ISO常用格式化,比如:yyyy-MM-dd’T’HH:mm:ssZ

    /**
     * 时区时间格式化和ISO常用格式化
     * YYYY_MM_DD_T_HH_MM_SS_Z = "yyyy-MM-dd'T'HH:mm:ssZ"
     */
    @Test
    public void zonedDateTimeFormatTest(){
        //默认为系统时区
        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        //2020-02-18T22:37:55+0800
        System.out.println(DateTimeFormatterUtil.format(zonedDateTime, DateTimeFormatterUtil.YYYY_MM_DD_T_HH_MM_SS_Z_FMT));
        
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_DATE_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_DATE_TIME_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_INSTANT_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_LOCAL_DATE_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_LOCAL_DATE_TIME_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_LOCAL_TIME_FMT));
        
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_TIME_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_WEEK_DATE_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.ISO_ZONED_DATE_TIME_FMT));
        System.out.println(zonedDateTime.format(DateTimeFormatterUtil.BASIC_ISO_DATE_FMT));
    }

 

输出:

2020-02-19T13:47:13+0800
2020-02-19+08:00
2020-02-19T13:47:13.271+08:00[Asia/Shanghai]
2020-02-19T05:47:13.271Z
2020-02-19
2020-02-19T13:47:13.271
13:47:13.271
13:47:13.271+08:00
2020-W08-3+08:00
2020-02-19T13:47:13.271+08:00[Asia/Shanghai]
20200219+0800

 

(2)时区时间解析

    /**
     * 时区时间解析
     * YYYY_MM_DD_T_HH_MM_SS_Z = "yyyy-MM-dd'T'HH:mm:ssZ"
     */
    @Test
    public void parseToZonedDateTimeTest(){
        String text = "2020-02-18T22:37:55+0800";
        ZonedDateTime zonedDateTime = DateTimeFormatterUtil.parseToZonedDateTime(text, DateTimeFormatterUtil.YYYY_MM_DD_T_HH_MM_SS_Z_FMT);
        System.out.println(zonedDateTime);
        
        String text2 = "2020-02-19T12:30:25.121+08:00[Asia/Shanghai]";
        ZonedDateTime zonedDateTime2 = DateTimeFormatterUtil.parseToZonedDateTime(text2, DateTimeFormatterUtil.ISO_ZONED_DATE_TIME_FMT);
        System.out.println(zonedDateTime2);
        
        ZonedDateTime zonedDateTime3 = ZonedDateTime.parse(text2);
        System.out.println(zonedDateTime3);
    }

 

输出:

2020-02-18T22:37:55+08:00
2020-02-19T12:30:25.121+08:00[Asia/Shanghai]
2020-02-19T12:30:25.121+08:00[Asia/Shanghai]

 

源代码地址:https://github.com/xkzhangsan/xk-time

部分参考:

https://www.cnblogs.com/xwdreamer/p/8761825.html