JDK8新特性之日期时间

目录

1、旧版日期时间 API 存在的问题

2、新日期时间 API介绍

3、对日期时间修改

4、JDK8的时间格式化与解析

5、Instant类

6、Duration/Period类: 计算日期时间差

7、JDK8的时间校正器

8、JDK8设置日期时间的时区


1、旧版日期时间 API 存在的问题

1. 设计很差: 在java.util和java.sql的包中都有日期类,java.util.Date同时包含日期和时间,而java.sql.Date仅包

含日期。此外用于格式化和解析的类在java.text包中定义。

2. 非线程安全:java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。

3. 时区处理麻烦:日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和

java.util.TimeZone类,但他们同样存在上述所有的问题。

2、新日期时间 API介绍

JDK 8中增加了一套全新的日期时间API,这套API设计合理,是线程安全的。新的日期及时间API位于 java.time 包中,下面是一些关键类。

LocalDate:表示日期,包含年月日,格式为2021-10-16

LocalTime:表示时间,包含时分秒,格式为:16:38:54.158549300

LocalDateTime:表示日期时间,包含年月日,时分秒,格式为:2021-09-06T1515:33:56.750

DateTimeFormatter:日期时间格式化类

Instant:时间戳,表示一个特定的时间瞬间

Duration:用于计算2个时间(LocalTime,时分秒)的距离

Period:用于计算2个日期(LocalDate,年月日)的距离

ZonedDateTime:包含时区的时间

Java中使用的历法是ISO 8601日历系统,它是世界民用历法,也是我们所说的公历,平年365天,闰年366天。此外,java8还提供了4套其他历法:

ThaiBuddhistDate:泰国佛教历

MinguoDate:中华民国历

JapaneseDate:日本历

HijrahDate:伊斯兰历

JDK8的日期和时间类

LocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。提供了简单的日期和时间,并不包括当前的时间信息,也不包含与时区相关的信息。

//操作LocalDate类
@Test
public void testLocalDate(){
    //创建指定日期
    LocalDate date = LocalDate.of(1985, 10, 12);
    System.out.println("指定的时间是 : "+date);
    //得到当前日期
    LocalDate now = LocalDate.now();
    System.out.println("当前日期 : "+now);
    //获取日期信息
    System.out.println("年 : "+now.getYear());
    System.out.println("月 : "+now.getMonthValue());
    System.out.println("日 : "+now.getDayOfMonth());
    System.out.println("星期 :"+now.getDayOfWeek());
    System.out.println("一年中的第 : "+now.getDayOfYear()+"  : 天");
}

//操作LocalTime类:获取时间信息,格式为:16:38:54:158549300
@Test
public void testLocalTime(){
    //得到指定时间
    LocalTime time = LocalTime.of(9, 54, 32, 129_900_000);
    System.out.println("指定时间是 : "+time);
    //得到当前时间
    LocalTime now = LocalTime.now();
    System.out.println("当前时间 : "+now);
    //获取时间信息
    System.out.println("小时: "+now.getHour());
    System.out.println("分钟: "+now.getMinute());
    System.out.println("秒 :"+now.getSecond());
    System.out.println("纳秒 : "+now.getNano());
}

//LocalDateTime类:获取日期时间信息,2018-09-06T15:33:56.750
@Test
public  void testLocalDateTime(){
    //获取指定日期时间
    LocalDateTime dateTime = LocalDateTime.of(2018, 9, 23, 10, 10, 45, 730);
    System.out.println("指定日期时间是 : "+dateTime);
    //得到当前日期时间
    LocalDateTime now = LocalDateTime.now();
    System.out.println("当前日期时间是 : "+now);
    //获取日期时间
    System.out.println("年 : "+now.getYear());
    System.out.println("月 : "+now.getMonthValue());
    System.out.println("日 :"+now.getDayOfMonth());
    System.out.println("小时 : "+now.getHour());
    System.out.println("分钟 : "+now.getMinute());
    System.out.println("秒 : "+now.getSecond());
    System.out.println("纳秒 : "+now.getNano());
}

3、对日期时间修改

对已存在的LocalDate对象,创建它的修改版,最简单的方式就是使用withAttribute方法。withAttribute方法会创建对象的一个副本,并按照需要修改它的属性,以下所有的方法都返回了一个修改属性的对象,他们不会影响原来的对象。

//LocalDateTime类:对日期时间的修改
@Test
public void testUpdate(){
    LocalDateTime now = LocalDateTime.now();
    System.out.println("当前系统日期时间 : "+now);
    //修改日期时间
    LocalDateTime year = now.withYear(2071);
    System.out.println("修改的年份是 : "+year);
    System.out.println("now == year : "+(now==year));
    System.out.println("修改的月份 : "+now.withMonth(9));
    System.out.println("修改的日 :"+now.withDayOfMonth(28));
    System.out.println("修改的小时  : "+now.withHour(12));
    System.out.println("修改的分钟 :"+now.withMinute(20));
    System.out.println("修改的秒 : "+now.withSecond(45));
    System.out.println("修改的纳秒 : "+now.withNano(750));

    //在当前对象上加上或减去指定的时间
    LocalDateTime localDateTime = now.plusDays(5);
    System.out.println("5天后 : "+localDateTime);
    System.out.println("10年后 : "+now.plusYears(10));
    System.out.println("20个月后 : "+now.plusMonths(20));

    System.out.println("20年前 : "+now.minusYears(20));
    System.out.println("5个月前  :"+now.minusMonths(5));
    System.out.println("100天前  ; "+now.minusDays(100));
}

//时间比较 在JDK8中,LocalDate类中使用isBefore(),isAfter(),equals()方法来比较
//两个日期,可直接进行比较
@Test
public void testCompare(){
    LocalDate now = LocalDate.now();
    LocalDate of = LocalDate.of(2019, 8, 23);
    System.out.println(now.equals(of)); //false
    System.out.println(now.isAfter(of)); //true
    System.out.println(now.isBefore(of)); //false
}

 4、JDK8的时间格式化与解析

通过java.time.format.DateTimeFormatter类可以进行日期时间解析与格式化

//DateTimeFormatter类进行时间日期格式化
@Test
public void testFormat(){
    //得到当前日期
    LocalDateTime now = LocalDateTime.now();
    //将当前日期时间格式化
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    //将日期的时间格式化为字符串
    String dateTime = now.format(formatter);
    System.out.println("格式化后的时间日期  : "+dateTime);
    //将字符串解析为日期时间
    LocalDateTime parse = LocalDateTime.parse("2024-09-04 08:29:13", formatter);
    System.out.println("解析后的日期时间  : "+parse);
}

5、Instant类

Instant时间戳,内部保存了从1970年1月1日00:00:00以来的秒和纳秒

//Instant类  时间戳/时间线
@Test
public  void testInstant(){
    Instant now = Instant.now();
    System.out.println("当前时间戳 : "+now);
    //获取从1970年1月1日00:00:00的秒
    System.out.println(now.getNano());
    System.out.println(now.getEpochSecond());
    System.out.println(now.toEpochMilli());
    System.out.println(System.currentTimeMillis());

    Instant instant = Instant.ofEpochSecond(5);
    Instant instant1 = Instant.ofEpochMilli(5);
    System.out.println(instant1);
    System.out.println(instant);
}

6、Duration/Period类: 计算日期时间差

        6.1、 Duration:用于计算2个时间(LocalTime,时分秒)的距离

        6.2. Period:用于计算2个日期(LocalDate,年月日)的距离

//JDK8的计算日期时间差类
//1.Duration:用于计算2个时间(LocalTime,时分秒)的距离
//2.Period:用于计算2个日期(LocalDate,年月日)的距离
@Test
public void testCha(){
    //Duration计算时间的距离
    LocalTime now = LocalTime.now();
    LocalTime time = LocalTime.of(14, 15, 20);
    Duration d = Duration.between(now, time);
    System.out.println("相差的天数 :"+d.toDays());
    System.out.println("相差的小时数  : "+d.toHours());
    System.out.println("相差的分钟 : "+d.toMinutes());
    System.out.println("相差的秒数  : "+d.toMillis());

    //Period计算日期的距离+
    LocalDate date = LocalDate.now();
    LocalDate date2 = LocalDate.of(2022, 12, 20);
    Period period = Period.between(date, date2);
    System.out.println("相差的年 : "+period.getYears());
    System.out.println("相差的月 : "+period.getMonths());
    System.out.println("相差的日  : "+period.getDays());
}

7、JDK8的时间校正器

需求:将日期调整到下个月的第一天 ,可以通过时间校正器来进行

TemporalAdjuster:时间校正器

TemporalAdjuster:该类通过静态方法提供了大量的常用的TemporalAdjuster的实现

//时间校正器 TemporalAdjuster
@Test
public void testTemporalAdjuster(){
    LocalDateTime now = LocalDateTime.now();
    //得到下个月的第一天
    TemporalAdjuster firstWeekDayofNextMonth = temporal -> {
        LocalDateTime dateTime = (LocalDateTime) temporal;
        LocalDateTime nextMonth = dateTime.plusMonths(1).withDayOfMonth(1);
        System.out.println("下个月的第一天 : "+nextMonth);
        return nextMonth;
    };
    LocalDateTime nextMonth = now.with(firstWeekDayofNextMonth);
    System.out.println("nextMonth :"+nextMonth);
}

8、JDK8设置日期时间的时区

java8中加入了对时区的支持,LocalDate、LocalTime、LocalDateTime是不带时区的,带时区的日期时间类分别为:ZonedDate、ZonedTime、ZonedDateTime。其中每个时区都对应着ID,ID的格式为"区域/城市"。如:Asia/shanghai等。

ZoneId:该类包含了所有时区信息。

//设置日期时间的时区
@Test
public void testZone(){
    //1.获取所有的时区ID
    //ZoneId.getAvailableZoneIds().forEach(System.out::println);
    //不带时间,获取计算机当前时间 中国使用的东八区的时区,比标准时间早8个小时
    LocalDateTime now = LocalDateTime.now();
    System.out.println("now : "+now);
    //操作带时区的类
    ZonedDateTime zonedDateTime = now(Clock.systemUTC());
    System.out.println(zonedDateTime);
    ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
    System.out.println("now 1 : "+now1);
    //now():使用计算机的默认时区,创建日期时间
    ZonedDateTime now2 = ZonedDateTime.now();
    System.out.println("now2 :"+now2);

    //使用指定的时区创建日期时间
    ZonedDateTime now3 = ZonedDateTime.now(ZoneId.of("America/Vancouver"));
    System.out.println("now3 : "+now3);
}

小结

详细学习了新的日期是时间相关类,LocalDate表示日期,包含年月日,LocalTime表示时间,包含时分

秒,LocalDateTime = LocalDate + LocalTime,时间的格式化和解析,通过DateTimeFormatter类型进行.

学习了Instant类,方便操作秒和纳秒,一般是给程序使用的.学习Duration/Period计算日期或时间的距离,还使用时间调

整器方便的调整时间,学习了带时区的3个类ZoneDate/ZoneTime/ZoneDateTime

JDK 8新的日期和时间 API的优势:

1. 新版的日期和时间API中,日期和时间对象是不可变的。操纵的日期不会影响老值,而是新生成一个实例。

2. 新的API提供了两种不同的时间表示方式,有效地区分了人和机器的不同需求。

3. TemporalAdjuster可以更精确的操纵日期,还可以自定义日期调整器。

4. 是线程安全的

路漫漫其修远兮,吾将上下而求索,希望此篇文章对大家有所帮助......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值