Java8新特性 新时间与日期API

       以前Java版本提供的时间API都不是线程安全的,都是可变的。当多个线程同时操作,就会出现线程安全问题。但是,在Java8之后,提供了新的操作时间的API,这些类都是不可变的,是线程安全的。
下面将用简单的代码,为各位读者展示基本的使用方法。

LocalDate、LocalTime、LocalDateTime

以上类的实例是不可变的对象,分别表示系统日期、时间、日期和时间,采用ISO 8601(国际标准化组织的国际标准)的日期和时间表示方法。提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。

    @Test
    public void test1() {
        //获取当前系统时间
        LocalDateTime nowDateTime = LocalDateTime.now();
        System.out.println(nowDateTime);

        //指定时分秒
        LocalDateTime newDate = LocalDateTime.of(2019, 7, 28, 14, 46, 51);
        System.out.println(newDate);

        //加上两年
        LocalDateTime years = nowDateTime.plusYears(2);
        System.out.println(years);
        //加一天
        LocalDateTime days = nowDateTime.plusDays(1);
        System.out.println(days);
        //减两个月
        LocalDateTime minusMonths = nowDateTime.minusMonths(2L);
        System.out.println(minusMonths);
        
        //获取年
        int year = nowDateTime.getYear();
        //获取月
        int monthValue = nowDateTime.getMonthValue();
        //获取日
        int dayOfMonth = nowDateTime.getDayOfMonth();
        //获取时
        int hour = nowDateTime.getHour();
        //获取分
        int minute = nowDateTime.getMinute();
        //获取秒
        int second = nowDateTime.getSecond();
        System.out.println(year + "-" + monthValue + "-" + dayOfMonth + " " + hour + ":" + minute + ":" + second);

    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
2019-08-01T10:56:47.931
2019-07-28T14:46:51
2021-08-01T10:56:47.931
2019-08-02T10:56:47.931
2019-06-01T10:56:47.931
2019-8-1 10:56:47

上面是一些基本操作,还有很多其他的方法,可以对应API文档,进行学习。

Instant

这个类用于在程序中记录事件的时间戳(以Unix元年:1970年1月1日00:00:00),该类在时间线上建立单个瞬时点。

    @Test
    public void test2() {
        //获取UTC 时区
        Instant now = Instant.now();
        System.out.println(now);

        //带偏移量的时间
        OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime);

        //毫秒
        long milli = now.toEpochMilli();
        System.out.println(milli);

        //改变秒,从(1970年1月1日00:00:00)开始的秒数
        Instant instant = Instant.ofEpochSecond(60);
        System.out.println(instant);

        Instant maxValue = Instant.MAX;
        Instant minValue = Instant.MIN;
        System.out.println("最大值范围:" + maxValue + "-最小值范围:" + minValue);
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
2019-08-01T03:09:09.297Z
2019-08-01T11:09:09.297+08:00
1564628949297
1970-01-01T00:01:00Z
最大值范围:+1000000000-12-31T23:59:59.999999999Z-最小值范围:-1000000000-01-01T00:00:00Z

Duration

这个类表示秒或纳秒时间间隔,适合处理较短的时间,需要更高的精确性。

    @Test
    public void test3() throws InterruptedException {
        Instant instant1 = Instant.now();
        Thread.sleep(1000L);
        Instant instant2 = Instant.now();

        //时间间隔
        Duration duration = Duration.between(instant1, instant2);
        System.out.println(duration.getSeconds());

        LocalTime localTime1 = LocalTime.now();
        Thread.sleep(1000L);
        LocalTime localTime2 = LocalTime.now();

        System.out.println(Duration.between(localTime1, localTime2).toMillis());
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
1
1001

Period

一般用于获取两个日期之间的差。

    @Test
    public void test4() {
        LocalDate localDate1 = LocalDate.now();
        LocalDate localDate2 = LocalDate.of(2019, 8, 8);

        //获取日期差
        Period period = Period.between(localDate1, localDate2);
        System.out.println(period.getYears() + ":" + period.getMonths() + ":" + period.getDays());

        //判断哪个时间大(false localDate1 早于 localDate2;true,localDate1 晚于 localDate2)
        System.out.println(period.isNegative());
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
0:0:7
false

TemporalAdjuster

时间校正器:有的时候需要对时间进行复杂的操作,例如,获取当前日期的"下个周日"、"下个工作日"等等…这些都能通过TemporalAdjuster类来实现。TemporalAdjusters这个工具类就像使用Stream API中的Collectors类一样,通过静态方法提供了大量的常用TemporalAdjuster的实现。

    @Test
    public void test5() {
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);

        //取本月第10天
        LocalDateTime localDateTime1 = localDateTime.withDayOfMonth(10);
        System.out.println(localDateTime1);

        //获取下一个周日
        LocalDateTime localDateTime2 = localDateTime.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
        System.out.println(localDateTime2);

        //获取本月最后一天
        LocalDateTime localDateTime3 = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println(localDateTime3);

        //自定义:下一个工作日
        LocalDateTime localDateTime5 = localDateTime.with((date) -> {
            LocalDateTime localDateTime4 = (LocalDateTime) date;
            DayOfWeek dayOfWeek = localDateTime4.getDayOfWeek();
            if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
                return localDateTime4.plusDays(3);
            } else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
                return localDateTime4.plusDays(2);
            } else {
                return localDateTime4.plusDays(1);
            }
        });
        System.out.println(localDateTime5);
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
2019-08-01T13:17:58.707
2019-08-10T13:17:58.707
2019-08-04T13:17:58.707
2019-08-31T13:17:58.707
2019-08-02T13:17:58.707

DateTimeFormatter

此类用于解析和格式化日期或时间。

    @Test
    public void test6() {
        //ISO日期格式化:如"2019-08-01"
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE;
        LocalDateTime localDateTime = LocalDateTime.now();

        String startDate = localDateTime.format(dateTimeFormatter);
        System.out.println(startDate);

        //自定义格式化样式
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        String patternDate1 = localDateTime.format(pattern);
        String patternDate2 = pattern.format(localDateTime);
        System.out.println(patternDate1);

        //将字符串转换为LocalDateTime对象
        LocalDateTime parseDate = LocalDateTime.parse(patternDate2, pattern);
        System.out.println(parseDate);
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
2019-08-01
2019年08月01日 13:20:25
2019-08-01T13:20:25

ZonedDateTime

该类用于表示带时区的日期与时间信息的类。

    @Test
    public void test7() {
        //获取所有时区
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
        zoneIds.forEach(System.out::println);
        
        //指定时区构建时间
        LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("America/Cuiaba"));
        System.out.println(localDateTime);

        LocalDateTime localDateTime1 = LocalDateTime.now();
        ZonedDateTime zonedDateTime = localDateTime1.atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println(zonedDateTime);       
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
2019-08-01T01:35:12.465
2019-08-01T13:35:12.470+08:00[Asia/Shanghai]

Date 转 (LocalDateTime、LocalDate、LocalTime)
    @Test
    public void test9() {
        Date date = new Date();
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = instant.atZone(zoneId);
        LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
        LocalDate localDate = zonedDateTime.toLocalDate();
        LocalTime localTime = zonedDateTime.toLocalTime();
        System.out.println(localDateTime);
        System.out.println(localDate);
        System.out.println(localTime);
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
2019-08-01T13:36:48.767
2019-08-01
13:36:48.767

(LocalDateTime、LocalDate) 转 Date
    @Test
    public void test10() {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime1 = LocalDateTime.now().atZone(zoneId);
        ZonedDateTime zonedDateTime2 = LocalDate.now().atStartOfDay(zoneId);
        Date date1 = Date.from(zonedDateTime1.toInstant());
        Date date2 = Date.from(zonedDateTime2.toInstant());
        System.out.println(date1);
        System.out.println(date2);
    }

结果:


C:\android\java\jdk1.8\bin\java.exe ...
Thu Aug 01 13:39:39 CST 2019
Thu Aug 01 00:00:00 CST 2019

本篇博文主要对Java8提供的新的时间和日期API做了简单的应用。关于其他方法,或者更复杂的操作,读者可查询Java8 官方文档。

Java8中文版 - 在线API中文手册 - 码工具 :http://www.matools.com/api/java8

上面链接是Java8的中文版文档,但是没有搜索功能,如果使用Google浏览器,可以通过Ctrl + f,输入关键字,来对网页全局搜索。

迷茫的时候,一个人静静,想想过往,终能走出迷茫。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值