zoukankan      html  css  js  c++  java
  • Java8简明学习之新时间日期API

      由于历史原因,在之前的版本里无论Date还是Calendar都非常难用,尤其在涉及到日期计算方面,而且其中日期转换的类DateForamt还是非线程安全的。
    也正因为难用,一般项目里面都引入第三方的类库操作时间,例如Joda-Time和apache-lang包的DateUtils类。
      基于上述种种原因,Java8新增了java.time包,其中包含了新的处理时间的类来解决上述问题。

    1.主要类:

    LocalDate、LocalTime、 Instant、 Duration 以及 Period

    LocalDate和LocalTime及LocalDateTime

    eg:

    @Test
        public void test8time() {
            // LocalDate
            // 创建LocalDate
            LocalDate localDate1 = LocalDate.of(2018, 7, 26);
            LocalDate localDate2 = LocalDate.now();
            LocalDate localDate3 = LocalDate.parse("2014-03-18");
            System.out.println(localDate1 + " " + localDate2 + " " + localDate3);
    
            int year = localDate1.getYear();
            Month month = localDate1.getMonth();
            int day = localDate1.getDayOfMonth();
            DayOfWeek dow = localDate1.getDayOfWeek();
            int len = localDate1.lengthOfMonth();
            // 是否闰年
            boolean leap = localDate1.isLeapYear();
    
            System.out.println(year);
            System.out.println(month);
            System.out.println(day);
            System.out.println(dow);
            System.out.println(len);
            System.out.println(leap);
    
            // 通过传递 TemporalField 来换取时间 类似于工厂模式
            // ChronoField此枚举实现了TemporalField接口
            int fieldYear = localDate1.get(ChronoField.YEAR);
            int fieldMonth = localDate1.get(ChronoField.MONTH_OF_YEAR);
            int fieldDay = localDate1.get(ChronoField.DAY_OF_MONTH);
            System.out.println(fieldYear);
            System.out.println(fieldMonth);
            System.out.println(fieldDay);
            // LocalTime
            // 创建LocalTime
            LocalTime time = LocalTime.of(11, 10, 20);
            LocalTime time1 = LocalTime.now();
            LocalTime time2 = LocalTime.parse("11:10:20");
            System.out.println(time + " " + time1 + " " + time2);
            System.out.println(String.join(" ", time.toString(), time1.toString(), time2.toString()));
    
            int hour = time.getHour();
            int minute = time.getMinute();
            int second = time.getSecond();
            System.out.println(hour);
            System.out.println(minute);
            System.out.println(second);
    
            int fieldHour = time.get(ChronoField.HOUR_OF_DAY);
            int fieldMinute = time.get(ChronoField.MINUTE_OF_HOUR);
            int fieldSecond = time.get(ChronoField.SECOND_OF_MINUTE);
            System.out.println(fieldHour);
            System.out.println(fieldMinute);
            System.out.println(fieldSecond);
    
            // 合并时间 创建LocalDateTime
            LocalDateTime ldt = LocalDateTime.of(localDate1, time);
            System.out.println(ldt);
            LocalDateTime ldt1 = LocalDateTime.now();
            System.out.println(ldt1);
    
            LocalDate ld = ldt1.toLocalDate();
            LocalTime lt = ldt1.toLocalTime();
            System.out.println(ld);
            System.out.println(lt);
        }

    Instant

    @Test
        public void testInstant() {
            // Instant 是以Unix元年时间开始所经历的秒数进行计算
            Instant instant = Instant.ofEpochSecond(1);
            System.out.println(instant);
            Instant instant1 = Instant.now();
            System.out.println(instant1);
        }

    Duration和Period
    Duration类主要用于以秒和纳秒衡量时间的长短。
    Period类主要以年、月或者日的方式衡量时间长短。

    @Test
        public void testDp() {
            LocalTime time1 = LocalTime.now();
            LocalTime time2 = LocalTime.now();
            LocalDateTime dateTime1 = LocalDateTime.now();
            LocalDateTime dateTime2 = LocalDateTime.now();
            Instant instant1 = Instant.now();
            Instant instant2 = Instant.now();
            Duration d1 = Duration.between(time1, time2);
            Duration d2 = Duration.between(dateTime1, dateTime2);
            Duration d3 = Duration.between(instant1, instant2);
    
            System.out.println(d1);
            System.out.println(d2);
            System.out.println(d3);
    
            // 创建
            Duration threeMinutes = Duration.ofMinutes(3);
            Duration threeMinutes1 = Duration.of(3, ChronoUnit.MINUTES);
            Period tenDays = Period.ofDays(10);
            Period threeWeeks = Period.ofWeeks(3);
            Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1);
    
            System.out.println(threeMinutes);
            System.out.println(threeMinutes1);
            System.out.println(tenDays);
            System.out.println(threeWeeks);
            System.out.println(twoYearsSixMonthsOneDay);
        }

    2.对日期的操作

    eg:

    @Test
        public void operaTime() {
            // 直接操作
            LocalDate date1 = LocalDate.of(2018, 7, 26);
            LocalDate date2 = date1.withYear(2017);
            LocalDate date3 = date2.withDayOfMonth(25);
            LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 4);
            LocalDate date5 = date1.withYear(2017).withMonth(4).withDayOfMonth(25);
            System.out.println(date4);
            System.out.println(date5);
    
            // 相对操作
            LocalDate date6 = LocalDate.of(2018, 7, 26);
            LocalDate date7 = date6.plusWeeks(1);
            LocalDate date8 = date7.minusYears(3);
            LocalDate date9 = date8.plus(6, ChronoUnit.MONTHS);
            LocalDate date10 = date6.plusWeeks(1).minusYears(3).plusMonths(6);
            System.out.println(date9);
            System.out.println(date10);
    
            // 使用 TemporalAdjuster 操作日期
            LocalDate date11 = LocalDate.now().with(lastDayOfMonth());
            System.out.println(date11);
    
        }

    TemporalAdjuster接口里面的静态方法
    dayOfWeekInMonth 创建一个新的日期,它的值为同一个月中每一周的第几天
    firstDayOfMonth 创建一个新的日期,它的值为当月的第一天
    firstDayOfNextMonth 创建一个新的日期,它的值为下月的第一天
    firstDayOfNextYear 创建一个新的日期,它的值为明年的第一天
    firstDayOfYear 创建一个新的日期,它的值为当年的第一天
    firstInMonth 创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值
    lastDayOfMonth 创建一个新的日期,它的值为当月的最后一天
    lastDayOfNextMonth 创建一个新的日期,它的值为下月的最后一天
    lastDayOfNextYear 创建一个新的日期,它的值为明年的最后一天
    lastDayOfYear 创建一个新的日期,它的值为今年的最后一天
    lastInMonth 创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值
    next/previous 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期
    nextOrSame/previousOrSame 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期,如果该日期已经符合要求,直接返回该对象

    对日期的解析DateTimeFormatter

    eg:

    @Test
        public void testFormat() {
            LocalDate ld = LocalDate.now();
            String ld1 = ld.format(DateTimeFormatter.BASIC_ISO_DATE);
            System.out.println(ld1);
    
            LocalDate ld2 = LocalDate.parse("20180726",
                    DateTimeFormatter.BASIC_ISO_DATE);
            System.out.println(ld2);
    
            LocalDateTime ld3 = LocalDateTime.now();
            ZoneId bjZone = ZoneId.of("Asia/Shanghai");
            // ZoneId zoneId = TimeZone.getDefault().toZoneId();
            ZonedDateTime adt = ld.atStartOfDay(bjZone);
            ZonedDateTime adt1 = ld3.atZone(bjZone);
            Instant instant = Instant.now();
            ZonedDateTime adt2 = instant.atZone(bjZone);
            System.out.println(adt);
            System.out.println(adt1);
            System.out.println(adt2);
        }

    3.Date, LocalDate, LocalDateTime和Instant之间的相互转换

      Date类新增了from和toInstant两个方法实现和Instant之间的互转,在通过Instant这个桥梁转换成LocalDate和LocalDateTime。

    @Test
        public void testDate2Local() {
            // Date转成LocalDateTime和LocalDate
            Date date = new Date();
            Instant instant = date.toInstant();
            ZoneId zone = ZoneId.systemDefault();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
            LocalDate localDate = localDateTime.toLocalDate();
            System.out.println(localDate);
            System.out.println(localDateTime);
    
            // LocalDate和LocalDateTime转成Date
            LocalDateTime localDateTime1 = LocalDateTime.now();
            ZonedDateTime zonedDateTime = localDateTime1.atZone(ZoneId.systemDefault());
            Instant instant1 = zonedDateTime.toInstant();
            Date date1 = Date.from(instant1);
            System.out.println(date1);
    
            LocalDate localDate1 = LocalDate.now();
            LocalDateTime localDateTime2 = localDate1.atStartOfDay();
            ZonedDateTime zonedDateTime1 = localDateTime2.atZone(ZoneId.systemDefault());
            Instant instant2 = zonedDateTime1.toInstant();
            Date date2 = Date.from(instant2);
            System.out.println(date2);
        }

    总结:

      新的API是时间处理变的简单,也解决了线程安全的问题,希望大家都能慢慢转过来。

    参考:

    《Java8实战》

  • 相关阅读:
    接收HttpPost请求路由可以不用带去掉参数
    吟唱一首
    C# XML反序列化解析成对象集合
    两个对象中相同属性赋值
    CefSharp 笔记-1
    C# 笔记--Label设置背景图片
    C# 笔记--VS 2017包下载超时,连接失败
    SQLite——C#查询表时 该字符串未被识别为有效的 DateTime 错误
    C# 笔记--Sendkeys
    C# 笔记——MeasureString准确测量
  • 原文地址:https://www.cnblogs.com/daily-note/p/9372138.html
Copyright © 2011-2022 走看看