添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
小眼睛的刺猬  ·  NDK library ...·  2 月前    · 
逃课的黑框眼镜  ·  nodejs http request ...·  1 年前    · 
踢足球的饺子  ·  js ...·  1 年前    · 

❤️点赞 👍 收藏 ⭐再看,养成习惯

大家好,我是小虚竹。之前有粉丝私聊我,问能不能把JAVA8 新的日期时间API(JSR-310)知识点梳理出来。答案是肯定的,谁让我宠粉呢。由于内容偏多,会拆成多篇来写。

闲话就聊到这,请看下面的正文。

常用的日期时间API简介

介绍下java8API比较常用的日期时间API,按 java.time 包的类顺序:

  • Clock:时钟
  • Instant:瞬间时间。
  • LocalDate:本地日期。只有表示年月日
  • LocalDateTime:本地日期时间,LocalDate+LocalTime
  • LocalTime:本地时间,只有表示时分秒
  • OffsetDateTime:有时间偏移量的日期时间(不包含基于ZoneRegion的时间偏移量)
  • OffsetTime:有时间偏移量的时间
  • ZonedDateTime:有时间偏移量的日期时间(包含基于ZoneRegion的时间偏移量)
  • 博主把这些类都点开看了,都是属于不可变类。而且官方也说了, java.time包 下的类都是线程安全的。

    Clock

    Clock类说明

    public abstract class Clock {
    

    Clock 是抽象类,内部提供了四个内部类,这是它的内部实现类

  • FixedClock :始终返回相同瞬间的时钟,通常使用于测试。
  • OffsetClock :偏移时钟,时间偏移量的单位是Duration。
  • SystemClock :系统默认本地时钟。
  • TickClock :偏移时钟,时间偏移量的单位是纳秒。
  • Clock 提供了下面这几个常用的方法(这几个方法在实现类里都有对应的实现):

    // 获取时钟的当前Instant对象。
    public abstract Instant instant()
    // 获取时钟的当前毫秒数值
    public long millis()
    // 获取用于创建时钟的时区。
    public abstract ZoneId	getZone()
    // 返回具有指定时区的当前时钟的新实例
    public abstract Clock withZone(ZoneId zone)
    

    FixedClock

    Clock.fixed

    public static Clock fixed(Instant fixedInstant, ZoneId zone)
    

    需要传递instantzone,并将返回具有固定瞬间的时钟。

    		Instant instant = Instant.now();
    		Clock fixedClock = Clock.fixed(instant, ZoneId.of("Asia/Shanghai"));
    		Clock fixedClock1 = Clock.fixed(instant, ZoneId.of("GMT"));
    		System.out.println("中国时区的Clock:"+fixedClock);
    		System.out.println("GMT时区的Clock:"+fixedClock1);
    

    由运行结果可知,返回的结果是有带对应时区的。

    验证获取的时钟会不会改变:

    		Clock clock = Clock.systemDefaultZone();
    		Clock fixedClock = Clock.fixed(clock.instant(), ZoneId.of("Asia/Shanghai"));
    		System.out.println(fixedClock.instant());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		System.out.println(fixedClock.instant());
    

    Clock.fixed 创建一个固定的时钟,clock 对象将始终提供与指定相同的时刻。。如图所示,强制睡眠1秒,但是时刻没变。

    Clock.fixed 跟 Offset 方法更配

    由上面可知Clock.fixed 得到一个固定的时钟,那要添加时间或者减去时间就要用到Offset 方法

    示例代码如下

    		Clock clock = Clock.systemDefaultZone();
    		Clock fixedClock = Clock.fixed(clock.instant(), ZoneId.of("Asia/Shanghai"));
    		System.out.println(fixedClock.instant());
    		Clock clockAdd = Clock.offset(clock, Duration.ofMinutes(20));
    		Clock clockSub = Clock.offset(clock, Duration.ofMinutes(-10));
    		System.out.println("原先的: " + clock.instant());
    		System.out.println("加了20分钟: " + clockAdd.instant());
    		System.out.println("减了10分钟: " + clockSub.instant());
    

    OffsetClock

    OffsetClock 是偏移时钟,时间偏移量的单位是Duration。

    //Clock
         public static Clock offset(Clock baseClock, Duration offsetDuration) {
            Objects.requireNonNull(baseClock, "baseClock");
            Objects.requireNonNull(offsetDuration, "offsetDuration");
            if (offsetDuration.equals(Duration.ZERO)) {
                return baseClock;
            return new OffsetClock(baseClock, offsetDuration);
    

    由源码可知,使用Clock.offset方法 返回的是OffsetClock实例对象

    		Clock clock = Clock.systemDefaultZone();
    		Clock fixedClock = Clock.fixed(clock.instant(), ZoneId.of("Asia/Shanghai"));
    		System.out.println(fixedClock.instant());
    		Clock clockAdd = Clock.offset(clock, Duration.ofMinutes(20));
    		System.out.println("原先的: " + clock.instant());
    		System.out.println("加了20分钟: " + clockAdd.instant());
    

    SystemClock

    SystemClock 是系统默认的本地时钟。

    		Clock clock = Clock.systemDefaultZone();
    		System.out.println(clock.millis());
    		Clock utc = Clock.systemUTC();
    		System.out.println(utc.millis());
    		System.out.println(System.currentTimeMillis());
    

    居然完全一样。这就要看下源码了

    Clock.systemDefaultZone()

    用的是系统默认的时区ZoneId.systemDefault()

        public static Clock systemDefaultZone() {
            return new SystemClock(ZoneId.systemDefault());
    

    最终调用的也是System.currentTimeMillis()

    Clock.systemUTC()

    用的是UTC时区ZoneOffset.UTC

        public static Clock systemUTC() {
            return new SystemClock(ZoneOffset.UTC);
    

    最终调用的也是System.currentTimeMillis()

    Clock.systemDefaultZone() 和Clock.systemUTC()获取的millis()时间戳是一样的,就是对应时区的差别。

    TickClock

    TickClock 是偏移时钟,时间偏移量的最小单位是纳秒。

    如图所示,Clock主要提供下面三个方法

    //构造的时钟的计时单位是自定义的偏移量单位
    public static Clock tick(Clock baseClock, Duration tickDuration);
     //构造的时钟的计时单位是分
     public static Clock tickMinutes(ZoneId zone);
    //构造的时钟的计时单位是秒
    public static Clock tickSeconds(ZoneId zone) ;
    
    		Clock tickClock = Clock.tick(Clock.systemDefaultZone(),Duration.ofHours(1L));
    		Clock tickMinutes = Clock.tickMinutes(ZoneId.of("Asia/Shanghai"));
    		Clock tickSeconds = Clock.tickSeconds(ZoneId.of("Asia/Shanghai"));
    		LocalDateTime tickClockLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(tickClock.millis()),ZoneId.of("Asia/Shanghai"));
    		LocalDateTime tickMinutesLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(tickMinutes.millis()),ZoneId.of("Asia/Shanghai"));
    		LocalDateTime tickSecondsLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(tickSeconds.millis()),ZoneId.of("Asia/Shanghai"));
    		System.out.println("tickClock  :"+tickClock.millis() +" 转为date时间:"+tickClockLocalDateTime);
    		System.out.println("tickMinutes:"+tickMinutes.millis() +" 转为date时间:"+tickMinutesLocalDateTime);
    		System.out.println("tickSeconds:"+tickSeconds.millis() +" 转为date时间:"+tickSecondsLocalDateTime);
    

    偏移量的单位支持:天,时,分,秒,豪秒,纳秒

    Instant

    Instant类说明

    public final class Instant
            implements Temporal, TemporalAdjuster, Comparable<Instant>, Serializable {
    

    Instant表示瞬间时间。也是不可变类且是线程安全的。其实Java.time 这个包是线程安全的。

    Instant是java 8新增的特性,里面有两个核心的字段

    private final long seconds; private final int nanos;

    一个是单位为秒的时间戳,另一个是单位为纳秒的时间戳。

    是不是跟**System.currentTimeMillis()**返回的long时间戳很像,System.currentTimeMillis()返回的是毫秒级,Instant多了更精确的纳秒级时间戳。

    Instant常用的用法

     		Instant now = Instant.now();
    		System.out.println("now:"+now);
    		System.out.println(now.getEpochSecond()); // 秒
    		System.out.println(now.toEpochMilli()); // 毫秒
    

    Instant是没有时区的,但是Instant加上时区后,可以转化为ZonedDateTime

    		Instant ins = Instant.now();
    		ZonedDateTime zdt = ins.atZone(ZoneId.systemDefault());
    		System.out.println(zdt);
    

    long型时间戳转Instant

    要注意long型时间戳的时间单位选择Instant对应的方法转化

    //1626796436 为秒级时间戳
    Instant ins = Instant.ofEpochSecond(1626796436);
    ZonedDateTime zdt = ins.atZone(ZoneId.systemDefault());
    System.out.println("秒级时间戳转化:"+zdt);
    //1626796436111l 为秒级时间戳
    Instant ins1 = Instant.ofEpochMilli(1626796436111l);
    ZonedDateTime zdt1 = ins1.atZone(ZoneId.systemDefault());
    System.out.println("毫秒级时间戳转化:"+zdt1);
    

    Instant的坑

    Instant.now()获取的时间与北京时间相差8个时区,这是一个细节,要避坑。

    看源码,用的是UTC时间。

    public static Instant now() {
            return Clock.systemUTC().instant();
    

    解决方案:

    Instant now = Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8));
    System.out.println("now:"+now);
    

    LocalDate

    LocalDate类说明

    LocalDate表示本地日期。只有表示年月日。相当于:yyyy-MM-dd。

    LocalDate常用的用法

    获取当前日期

    		LocalDate localDate1 = LocalDate.now();
    		LocalDate localDate2 = LocalDate.now(ZoneId.of("Asia/Shanghai"));
    		LocalDate localDate3 = LocalDate.now(Clock.systemUTC());
    		System.out.println("now         :"+localDate1);
    		System.out.println("now by zone :"+localDate2);
    		System.out.println("now by Clock:"+localDate3);
    

    获取localDate对象

    		LocalDate localDate1 = LocalDate.of(2021, 8, 14);
    		LocalDate localDate2 = LocalDate.parse("2021-08-14");
    		System.out.println(localDate1);
    		System.out.println(localDate2);
    

    获取指定日期的年月日

    		LocalDate localDate1 = LocalDate.of(2021, 8, 14);
    		// 当前日期年份:2021
    		System.out.println(localDate1.getYear());
    		// 当前日期月份对象:AUGUST
    		System.out.println(localDate1.getMonth());
    		// 当前日期月份:8
    		System.out.println(localDate1.getMonthValue());
    		// 该日期是当前周的第几天:6
    		System.out.println(localDate1.getDayOfWeek().getValue());
    		// 该日期是当前月的第几天:14
    		System.out.println(localDate1.getDayOfMonth());
    		// 该日期是当前年的第几天:226
    		System.out.println(localDate1.getDayOfYear());
    

    修改年月日

    		LocalDate localDate1 = LocalDate.of(2021, 8, 14);
    		// 修改该日期的年份:2022-08-14
    		System.out.println(localDate1.withYear(2022));
    		// 修改该日期的月份:2021-12-14
    		System.out.println(localDate1.withMonth(12));
    		// 修改该日期在当月的天数:2021-08-01
    		System.out.println(localDate1.withDayOfMonth(1));
    
    		LocalDate localDate1 = LocalDate.of(2021, 8, 14);
    		// 比较指定日期和参数日期,返回正数,那么指定日期时间较晚(数字较大):13
    		int i = localDate1.compareTo(LocalDate.of(2021, 8, 1));
    		System.out.println(i);
    		// 比较指定日期是否比参数日期早(true为早):true
    		System.out.println(localDate1.isBefore(LocalDate.of(2021,8,31)));
    		// 比较指定日期是否比参数日期晚(true为晚):false
    		System.out.println(localDate1.isAfter(LocalDate.of(2021,8,31)));
    		// 比较两个日期是否相等:true
    		System.out.println(localDate1.isEqual(LocalDate.of(2021, 8, 14)));
    

    LocalDate 和String相互转化、Date和LocalDate相互转化

    LocalDate 和String相互转化

    		LocalDate localDate1 = LocalDate.of(2021, 8, 14);
    		// LocalDate 转 String
    		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    		String dateString = localDate1.format(dateTimeFormatter);
    		System.out.println("LocalDate 转 String:"+dateString);
    		// String 转 LocalDate
    		String str = "2021-08-14";
    		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    		LocalDate date = LocalDate.parse(str, fmt);
    		System.out.println("String 转 LocalDate:"+date);
    

    Date和LocalDate相互转化

    	// Date 转 LocalDate
    		Date now = new Date();
    		// 先将Date转换为ZonedDateTime
    		Instant instant = now.toInstant();
    		ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Shanghai"));
    		LocalDate localDate = zonedDateTime.toLocalDate();
    		// Sat Aug 14 23:16:28 CST 2021
    		System.out.println(now);
    		// 2021-08-14
    		System.out.println(localDate);
    		// LocalDate 转 Date
    		LocalDate now1 = LocalDate.now();
    		ZonedDateTime dateTime = now1.atStartOfDay(ZoneId.of("Asia/Shanghai"));
    		Date date1 = Date.from(dateTime.toInstant());
    		System.out.println(date1);
    

    LocalDateTime

    LocalDateTime类说明

    表示当前日期时间,相当于:yyyy-MM-ddTHH:mm:ss

    LocalDateTime常用的用法

    获取当前日期和时间

    		LocalDate d = LocalDate.now(); // 当前日期
    		LocalTime t = LocalTime.now(); // 当前时间
    		LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间
    		System.out.println(d); // 严格按照ISO 8601格式打印
    		System.out.println(t); // 严格按照ISO 8601格式打印
    		System.out.println(dt); // 严格按照ISO 8601格式打印
    

    由运行结果可行,本地日期时间通过now()获取到的总是以当前默认时区返回的

    获取指定日期和时间

    		LocalDate d2 = LocalDate.of(2021, 07, 14); // 2021-07-14, 注意07=07月
    		LocalTime t2 = LocalTime.of(13, 14, 20); // 13:14:20
    		LocalDateTime dt2 = LocalDateTime.of(2021, 07, 14, 13, 14, 20);
    		LocalDateTime dt3 = LocalDateTime.of(d2, t2);
    		System.out.println("指定日期时间:"+dt2);
    		System.out.println("指定日期时间:"+dt3);
    

    日期时间的加减法及修改

    		LocalDateTime currentTime = LocalDateTime.now(); // 当前日期和时间
    		System.out.println("------------------时间的加减法及修改-----------------------");
    		//3.LocalDateTime的加减法包含了LocalDate和LocalTime的所有加减,上面说过,这里就只做简单介绍
    		System.out.println("3.当前时间:" + currentTime);
    		System.out.println("3.当前时间加5年:" + currentTime.plusYears(5));
    		System.out.println("3.当前时间加2个月:" + currentTime.plusMonths(2));
    		System.out.println("3.当前时间减2天:" + currentTime.minusDays(2));
    		System.out.println("3.当前时间减5个小时:" + currentTime.minusHours(5));
    		System.out.println("3.当前时间加5分钟:" + currentTime.plusMinutes(5));
    		System.out.println("3.当前时间加20秒:" + currentTime.plusSeconds(20));
    		//还可以灵活运用比如:向后加一年,向前减一天,向后加2个小时,向前减5分钟,可以进行连写
    		System.out.println("3.同时修改(向后加一年,向前减一天,向后加2个小时,向前减5分钟):" + currentTime.plusYears(1).minusDays(1).plusHours(2).minusMinutes(5));
    		System.out.println("3.修改年为2025年:" + currentTime.withYear(2025));
    		System.out.println("3.修改月为12月:" + currentTime.withMonth(12));
    		System.out.println("3.修改日为27日:" + currentTime.withDayOfMonth(27));
    		System.out.println("3.修改小时为12:" + currentTime.withHour(12));
    		System.out.println("3.修改分钟为12:" + currentTime.withMinute(12));
    		System.out.println("3.修改秒为12:" + currentTime.withSecond(12));
    

    LocalDateTime和Date相互转化

    Date转LocalDateTime

    		System.out.println("------------------方法一:分步写-----------------------");
    		//实例化一个时间对象
    		Date date = new Date();
    		//返回表示时间轴上同一点的瞬间作为日期对象
    		Instant instant = date.toInstant();
    		//获取系统默认时区
    		ZoneId zoneId = ZoneId.systemDefault();
    		//根据时区获取带时区的日期和时间
    		ZonedDateTime zonedDateTime = instant.atZone(zoneId);
    		//转化为LocalDateTime
    		LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
    		System.out.println("方法一:原Date = " + date);
    		System.out.println("方法一:转化后的LocalDateTime = " + localDateTime);
    		System.out.println("------------------方法二:一步到位(推荐使用)-----------------------");
    		//实例化一个时间对象
    		Date todayDate = new Date();
    		//Instant.ofEpochMilli(long l)使用1970-01-01T00:00:00Z的纪元中的毫秒来获取Instant的实例
    		LocalDateTime ldt = Instant.ofEpochMilli(todayDate.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
    		System.out.println("方法二:原Date = " + todayDate);
    		System.out.println("方法二:转化后的LocalDateTime = " + ldt);
    

    LocalDateTime转Date

    		System.out.println("------------------方法一:分步写-----------------------");
    		//获取LocalDateTime对象,当前时间
    		LocalDateTime localDateTime = LocalDateTime.now();
    		//获取系统默认时区
    		ZoneId zoneId = ZoneId.systemDefault();
    		//根据时区获取带时区的日期和时间
    		ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
    		//返回表示时间轴上同一点的瞬间作为日期对象
    		Instant instant = zonedDateTime.toInstant();
    		//转化为Date
    		Date date = Date.from(instant);
    		System.out.println("方法一:原LocalDateTime = " + localDateTime);
    		System.out.println("方法一:转化后的Date = " + date);
    		System.out.println("------------------方法二:一步到位(推荐使用)-----------------------");
    		//实例化一个LocalDateTime对象
    		LocalDateTime now = LocalDateTime.now();
    		//转化为date
    		Date dateResult = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
    		System.out.println("方法二:原LocalDateTime = " + now);
    		System.out.println("方法二:转化后的Date = " + dateResult);
    

    LocalTime

    LocalTime类说明

    LocalTime:本地时间,只有表示时分秒

    LocalTime常用的用法

    获取当前时间

    		LocalTime localTime1 = LocalTime.now();
    		LocalTime localTime2 = LocalTime.now(ZoneId.of("Asia/Shanghai"));
    		LocalTime localTime3 = LocalTime.now(Clock.systemDefaultZone());
    		System.out.println("now         :"+localTime1);
    		System.out.println("now by zone :"+localTime2);
    		System.out.println("now by Clock:"+localTime3);
    

    获取LocalTime对象

    		LocalTime localTime1 = LocalTime.of(23, 26, 30);
    		LocalTime localTime2 = LocalTime.of(23, 26);
    		System.out.println(localTime1);
    		System.out.println(localTime2);
    

    获取指定日期的时分秒

    		LocalTime localTime1 = LocalTime.of(23, 26, 30);
    		//当前时间的时:23
    		System.out.println(localTime1.getHour());
    		//当前时间的分:26
    		System.out.println(localTime1.getMinute());
    		//当前时间的秒:30
    		System.out.println(localTime1.getSecond());
    

    修改时分秒

    		LocalTime localTime1 = LocalTime.of(23, 26, 30);
    		//修改时间的时:00:26:30
    		System.out.println(localTime1.withHour(0));
    		//修改时间的分:23:30:30
    		System.out.println(localTime1.withMinute(30));
    		//修改时间的秒:23:26:59
    		System.out.println(localTime1.withSecond(59));
    
    		LocalTime localTime1 = LocalTime.of(23, 26, 30);
    		LocalTime localTime2 = LocalTime.of(23, 26, 32);
    		// 两个时间进行比较 大返回1,小就返回-1,一样就返回0:-1
    		System.out.println(localTime1.compareTo(localTime2));
    		// 比较指定时间是否比参数时间早(true为早):true
    		System.out.println(localTime1.isBefore(localTime2));
    		// 比较指定时间是否比参数时间晚(true为晚):false
    		System.out.println(localTime1.isAfter(localTime2));
    		// 比较两个时间是否相等:true
    		System.out.println(localTime1.equals(LocalTime.of(23, 26, 30)));
    

    OffsetDateTime

    OffsetDateTime类说明

    OffsetDateTime:有时间偏移量的日期时间(不包含基于ZoneRegion的时间偏移量)

    public final class OffsetDateTime
            implements Temporal, TemporalAdjuster, Comparable<OffsetDateTime>, Serializable {
        //The minimum supported {@code OffsetDateTime}, '-999999999-01-01T00:00:00+18:00' 
        public static final OffsetDateTime MIN = LocalDateTime.MIN.atOffset(ZoneOffset.MAX);
        // The maximum supported {@code OffsetDateTime}, '+999999999-12-31T23:59:59.999999999-18:00'.
        public static final OffsetDateTime MAX = LocalDateTime.MAX.atOffset(ZoneOffset.MIN);
    

    上面的MINMAX 是公有静态变量。

    OffsetDateTime常用的用法

    获取当前日期时间

    		OffsetDateTime offsetDateTime1 = OffsetDateTime.now();
    		OffsetDateTime offsetDateTime2 = OffsetDateTime.now(ZoneId.of("Asia/Shanghai"));
    		OffsetDateTime offsetDateTime3 = OffsetDateTime.now(Clock.systemUTC());
    		System.out.println("now         :"+offsetDateTime1);
    		System.out.println("now by zone :"+offsetDateTime2);
    		System.out.println("now by Clock:"+offsetDateTime3);
    

    获取OffsetDateTime对象

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		OffsetDateTime offsetDateTime1 = OffsetDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		OffsetDateTime offsetDateTime2 = OffsetDateTime. of(2021, 8, 15, 13, 14, 20,0, ZoneOffset.ofHours(8));
    		Instant now = Instant.now();
    		OffsetDateTime offsetDateTime3 = OffsetDateTime.ofInstant(now, ZoneId.of("Asia/Shanghai"));
    		System.out.println(offsetDateTime1);
    		System.out.println(offsetDateTime2);
    		System.out.println(offsetDateTime3);
    

    获取指定日期的年月日时分秒

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		OffsetDateTime offsetDateTime1 = OffsetDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		//当前时间的年:2021
    		System.out.println(offsetDateTime1.getYear());
    		//当前时间的月:8
    		System.out.println(offsetDateTime1.getMonthValue());
    		//当前时间的日:15
    		System.out.println(offsetDateTime1.getDayOfMonth());
    		//当前时间的时:13
    		System.out.println(offsetDateTime1.getHour());
    		//当前时间的分:14
    		System.out.println(offsetDateTime1.getMinute());
    		//当前时间的秒:20
    		System.out.println(offsetDateTime1.getSecond());
    

    修改年月日时分秒

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		OffsetDateTime offsetDateTime1 = OffsetDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		//修改时间的年:2022-08-15T13:14:20+08:00
    		System.out.println(offsetDateTime1.withYear(2022));
    		//修改时间的月:2021-09-15T13:14:20+08:00
    		System.out.println(offsetDateTime1.withMonth(9));
    		//修改时间的日:2021-08-30T13:14:20+08:00
    		System.out.println(offsetDateTime1.withDayOfMonth(30));
    		//修改时间的时:2021-08-15T00:14:20+08:00
    		System.out.println(offsetDateTime1.withHour(0));
    		//修改时间的分:2021-08-15T13:30:20+08:00
    		System.out.println(offsetDateTime1.withMinute(30));
    		//修改时间的秒:2021-08-15T13:14:59+08:00
    		System.out.println(offsetDateTime1.withSecond(59));
    

    比较日期时间

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		OffsetDateTime offsetDateTime1 = OffsetDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		OffsetDateTime offsetDateTime3 = OffsetDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		LocalDateTime localDateTime2 = LocalDateTime.of(2021, 8, 15, 13, 14, 30);
    		OffsetDateTime offsetDateTime2 = OffsetDateTime.of(localDateTime2, ZoneOffset.ofHours(8));
    		// 两个时间进行比较 大返回1,小就返回-1,一样就返回0:-1
    		System.out.println(offsetDateTime1.compareTo(offsetDateTime2));
    		// 比较指定时间是否比参数时间早(true为早):true
    		System.out.println(offsetDateTime1.isBefore(offsetDateTime2));
    		// 比较指定时间是否比参数时间晚(true为晚):false
    		System.out.println(offsetDateTime1.isAfter(offsetDateTime2));
    		// 比较两个时间是否相等:true
    		System.out.println(offsetDateTime1.equals(offsetDateTime3));
    

    字符串转化为OffsetDateTime对象

    				String str = "2021-08-15T10:15:30+08:00";
    		OffsetDateTime offsetDateTime1 = OffsetDateTime.parse(str);
    		OffsetDateTime offsetDateTime2 = OffsetDateTime.parse(str,DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    		System.out.println(offsetDateTime1);
    		System.out.println(offsetDateTime2);
    

    OffsetTime

    OffsetTime类说明

    OffsetTime:有时间偏移量的时间

    public final class OffsetTime
            implements Temporal, TemporalAdjuster, Comparable<OffsetTime>, Serializable {
       //The minimum supported {@code OffsetTime}, '00:00:00+18:00'.
        public static final OffsetTime MIN = LocalTime.MIN.atOffset(ZoneOffset.MAX);
        //The maximum supported {@code OffsetTime}, '23:59:59.999999999-18:00'.
        public static final OffsetTime MAX = LocalTime.MAX.atOffset(ZoneOffset.MIN);
    

    上面的MINMAX 是公有静态变量。

    OffsetTime常用的用法

    获取当前时间

    		OffsetTime offsetTime1 = OffsetTime.now();
    		OffsetTime offsetTime2 = OffsetTime.now(ZoneId.of("Asia/Shanghai"));
    		OffsetTime offsetTime3 = OffsetTime.now(Clock.systemUTC());
    		System.out.println("now         :"+offsetTime1);
    		System.out.println("now by zone :"+offsetTime2);
    		System.out.println("now by Clock:"+offsetTime3);
    

    获取OffsetTime对象

    		LocalTime localTime1 = LocalTime.of(13, 14, 20);
    		OffsetTime offsetTime1 = OffsetTime.of(localTime1, ZoneOffset.ofHours(8));
    		OffsetTime offsetTime2 = OffsetTime. of(13, 14, 20,0, ZoneOffset.ofHours(8));
    		Instant now = Instant.now();
    		OffsetTime offsetTime3 = OffsetTime.ofInstant(now, ZoneId.of("Asia/Shanghai"));
    		System.out.println(offsetTime1);
    		System.out.println(offsetTime2);
    		System.out.println(offsetTime3);
    

    获取指定时间的时分秒

    		LocalTime localTime1 = LocalTime.of( 13, 14, 20);
    		OffsetTime offsetTime1 = OffsetTime.of(localTime1, ZoneOffset.ofHours(8));
    		//当前时间的时:13
    		System.out.println(offsetTime1.getHour());
    		//当前时间的分:14
    		System.out.println(offsetTime1.getMinute());
    		//当前时间的秒:20
    		System.out.println(offsetTime1.getSecond());
    

    修改时分秒

    		LocalTime localTime1 = LocalTime.of( 13, 14, 20);
    		OffsetTime offsetTime1 = OffsetTime.of(localTime1, ZoneOffset.ofHours(8));
    		//修改时间的时:00:14:20+08:00
    		System.out.println(offsetTime1.withHour(0));
    		//修改时间的分:13:30:20+08:00
    		System.out.println(offsetTime1.withMinute(30));
    		//修改时间的秒:13:14:59+08:00
    		System.out.println(offsetTime1.withSecond(59));
    
    		LocalTime localTime1 = LocalTime.of( 13, 14, 20);
    		OffsetTime offsetTime1 = OffsetTime.of(localTime1, ZoneOffset.ofHours(8));
    		OffsetTime offsetTime3 = OffsetTime.of(localTime1, ZoneOffset.ofHours(8));
    		LocalTime localTime2 = LocalTime.of(13, 14, 30);
    		OffsetTime offsetTime2 = OffsetTime.of(localTime2, ZoneOffset.ofHours(8));
    		// 两个时间进行比较 大返回1,小就返回-1,一样就返回0:-1
    		System.out.println(offsetTime1.compareTo(offsetTime2));
    		// 比较指定时间是否比参数时间早(true为早):true
    		System.out.println(offsetTime1.isBefore(offsetTime2));
    		// 比较指定时间是否比参数时间晚(true为晚):false
    		System.out.println(offsetTime1.isAfter(offsetTime2));
    		// 比较两个时间是否相等:true
    		System.out.println(offsetTime1.equals(offsetTime3));
    

    ZonedDateTime

    ZonedDateTime类说明

    表示一个带时区的日期和时间,ZonedDateTime可以理解为LocalDateTime+ZoneId

    从源码可以看出来,ZonedDateTime类中定义了LocalDateTime和ZoneId两个变量。

    且ZonedDateTime类也是不可变类且是线程安全的。

    public final class ZonedDateTime
            implements Temporal, ChronoZonedDateTime<LocalDate>, Serializable {
         * Serialization version.
        private static final long serialVersionUID = -6260982410461394882L;
         * The local date-time.
        private final LocalDateTime dateTime;
         * The time-zone.
        private final ZoneId zone;
    

    ZonedDateTime常用的用法

    获取当前日期时间

    		// 默认时区获取当前时间
    		ZonedDateTime zonedDateTime = ZonedDateTime.now();
    		// 用指定时区获取当前时间,Asia/Shanghai为上海时区
    		ZonedDateTime zonedDateTime1 = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
    		//withZoneSameInstant为转换时区,参数为ZoneId
    		ZonedDateTime zonedDateTime2 = zonedDateTime.withZoneSameInstant(ZoneId.of("America/New_York"));
    		System.out.println(zonedDateTime);
    		System.out.println(zonedDateTime1);
    		System.out.println(zonedDateTime2);
    
    		ZonedDateTime zonedDateTime1 = ZonedDateTime.now();
    		ZonedDateTime zonedDateTime2 = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
    		ZonedDateTime zonedDateTime3 = ZonedDateTime.now(Clock.systemUTC());
    		System.out.println("now         :"+zonedDateTime1);
    		System.out.println("now by zone :"+zonedDateTime2);
    		System.out.println("now by Clock:"+zonedDateTime3);
    

    获取ZonedDateTime对象

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		ZonedDateTime zonedDateTime2 = ZonedDateTime. of(2021, 8, 15, 13, 14, 20,0, ZoneOffset.ofHours(8));
    		Instant now = Instant.now();
    		ZonedDateTime zonedDateTime3 = ZonedDateTime.ofInstant(now, ZoneId.of("Asia/Shanghai"));
    		System.out.println(zonedDateTime1);
    		System.out.println(zonedDateTime2);
    		System.out.println(zonedDateTime3);
    

    获取指定日期的年月日时分秒

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		//当前时间的年:2021
    		System.out.println(zonedDateTime1.getYear());
    		//当前时间的月:8
    		System.out.println(zonedDateTime1.getMonthValue());
    		//当前时间的日:15
    		System.out.println(zonedDateTime1.getDayOfMonth());
    		//当前时间的时:13
    		System.out.println(zonedDateTime1.getHour());
    		//当前时间的分:14
    		System.out.println(zonedDateTime1.getMinute());
    		//当前时间的秒:20
    		System.out.println(zonedDateTime1.getSecond());
    

    修改年月日时分秒

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		//修改时间的年:2022-08-15T13:14:20+08:00
    		System.out.println(zonedDateTime1.withYear(2022));
    		//修改时间的月:2021-09-15T13:14:20+08:00
    		System.out.println(zonedDateTime1.withMonth(9));
    		//修改时间的日:2021-08-30T13:14:20+08:00
    		System.out.println(zonedDateTime1.withDayOfMonth(30));
    		//修改时间的时:2021-08-15T00:14:20+08:00
    		System.out.println(zonedDateTime1.withHour(0));
    		//修改时间的分:2021-08-15T13:30:20+08:00
    		System.out.println(zonedDateTime1.withMinute(30));
    		//修改时间的秒:2021-08-15T13:14:59+08:00
    		System.out.println(zonedDateTime1.withSecond(59));
    

    比较日期时间

    		LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20);
    		ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		ZonedDateTime zonedDateTime3 = ZonedDateTime.of(localDateTime1, ZoneOffset.ofHours(8));
    		LocalDateTime localDateTime2 = LocalDateTime.of(2021, 8, 15, 13, 14, 30);
    		ZonedDateTime zonedDateTime2 = ZonedDateTime.of(localDateTime2, ZoneOffset.ofHours(8));
    		// 两个时间进行比较 大返回1,小就返回-1,一样就返回0:-1
    		System.out.println(zonedDateTime1.compareTo(zonedDateTime2));
    		// 比较指定时间是否比参数时间早(true为早):true
    		System.out.println(zonedDateTime1.isBefore(zonedDateTime2));
    		// 比较指定时间是否比参数时间晚(true为晚):false
    		System.out.println(zonedDateTime1.isAfter(zonedDateTime2));
    		// 比较两个时间是否相等:true
    		System.out.println(zonedDateTime1.equals(zonedDateTime3));
    

    LocalDateTime+ZoneId变ZonedDateTime

    		LocalDateTime localDateTime = LocalDateTime.now();
    		ZonedDateTime zonedDateTime1 = localDateTime.atZone(ZoneId.systemDefault());
    		ZonedDateTime zonedDateTime2 = localDateTime.atZone(ZoneId.of("America/New_York"));
    		System.out.println(zonedDateTime1);
    		System.out.println(zonedDateTime2);
    

    上面的例子说明了,LocalDateTime是可以转成ZonedDateTime的。

    推荐相关文章

    hutool日期时间系列文章

    1DateUtil(时间工具类)-当前时间和当前时间戳

    2DateUtil(时间工具类)-常用的时间类型Date,DateTime,Calendar和TemporalAccessor(LocalDateTime)转换

    3DateUtil(时间工具类)-获取日期的各种内容

    4DateUtil(时间工具类)-格式化时间

    5DateUtil(时间工具类)-解析被格式化的时间

    6DateUtil(时间工具类)-时间偏移量获取

    7DateUtil(时间工具类)-日期计算

    8ChineseDate(农历日期工具类)

    9LocalDateTimeUtil(JDK8+中的{@link LocalDateTime} 工具类封装)

    10TemporalAccessorUtil{@link TemporalAccessor} 工具类封装

    要探索JDK的核心底层源码,那必须掌握native用法

    万字博文教你搞懂java源码的日期和时间相关用法

    java的SimpleDateFormat线程不安全出问题了,虚竹教你多种解决方案

    源码分析:JDK获取默认时区的风险和最佳实践

    分类:
    后端
    标签: