美文网首页Java 8
Java 8 | Date and Time

Java 8 | Date and Time

作者: 懒癌正患者 | 来源:发表于2018-04-22 21:45 被阅读7次

    在刚学习 Java 时间 API 的时候,我的内心其实是拒绝的,内心只有一个想法,这 TM 太麻烦了吧。原来的时间 API 我也不太了解,Java 8 既然提供了新的时间 API,我们就来学习一下新的 API 吧,旧的就让它成为过去式吧。

    代表日期、时间和时区的新类

    有3个类来替代原来的 Date 类,这3个类分别是 LocalDate, LocalTimeLocalDateTime

    LocalDate

    LocalDate 代表日期,没有时间和时区的概念。

    LocalDate localDate = LocalDate.now();
    System.out.println(localDate.toString());                //2018-04-22
    System.out.println(localDate.getDayOfWeek().toString()); //SUNDAY
    System.out.println(localDate.getDayOfMonth());           //22
    System.out.println(localDate.getDayOfYear());            //112
    System.out.println(localDate.isLeapYear());              //false
    System.out.println(localDate.plusDays(12).toString());   //2018-05-04
    

    LocalTime

    LocalTime 代表时间,没有日期和时区的概念。

    //LocalTime localTime = LocalTime.now();     //toString() in format 19:13:33.291
    LocalTime localTime = LocalTime.of(12, 20);
    System.out.println(localTime.toString());    //12:20
    System.out.println(localTime.getHour());     //12
    System.out.println(localTime.getMinute());   //20
    System.out.println(localTime.getSecond());   //0
    System.out.println(localTime.MIDNIGHT);      //00:00
    System.out.println(localTime.NOON);          //12:00
    

    LocalDateTime

    LocalDateTime 代表日期时间,没有时区的概念。

    LocalDateTime localDateTime = LocalDateTime.now();
    System.out.println(localDateTime.toString());      //2018-04-15T10:01:14.911
    System.out.println(localDateTime.getDayOfMonth()); //15
    System.out.println(localDateTime.getHour());       //10
    System.out.println(localDateTime.getNano());       //911000000
    

    如果我们需要带上有时区信息,那么可以使用另外3个相似的类OffsetDate, OffsetTimeOffsetDateTime。时区偏移可以用 “+05:30” or “Europe/Paris” 格式来表示。Java 通过一个 ZoneId 类来表示。

    OffsetDateTime offsetDateTime = OffsetDateTime.now();
    System.out.println(offsetDateTime.toString());              //2018-04-22T19:27:23.117+08:00
    
    offsetDateTime = OffsetDateTime.now(ZoneId.of("+05:30"));
    System.out.println(offsetDateTime.toString());              //2018-04-22T16:57:23.117+05:30
    
    offsetDateTime = OffsetDateTime.now(ZoneId.of("-06:30"));
    System.out.println(offsetDateTime.toString());              //2018-04-22T04:57:23.117-06:30
    
    ZonedDateTime zonedDateTime =
            ZonedDateTime.now(ZoneId.of("Europe/Paris"));
    System.out.println(zonedDateTime.toString());               //2018-04-22T13:27:23.120+02:00[Europe/Paris]
    

    代表时间戳和时间区间的新类

    ** Instant**

    Instant 代表任意时刻的时间戳,精度达到了纳秒。对 Instant 包括 与另外一个 Instant 进行对比,加减一段时间区间。

    Instant instant = Instant.now();
    System.out.println(instant.toString());                                 //2018-04-22T11:29:05.299Z
    System.out.println(instant.plus(Duration.ofMillis(5000)).toString());   //2018-04-22T11:29:10.299Z
    System.out.println(instant.minus(Duration.ofMillis(5000)).toString());  //2018-04-22T11:29:00.299Z
    System.out.println(instant.minusSeconds(10).toString());                //2018-04-22T11:28:55.299Z
    

    Duration

    Duration 代表2个时间戳的差值,即时间区间。

    Duration duration = Duration.ofMillis(5000);
    System.out.println(duration.toString());     //PT5S
     
    duration = Duration.ofSeconds(60);
    System.out.println(duration.toString());     //PT1M
     
    duration = Duration.ofMinutes(10);
    System.out.println(duration.toString());     //PT10M
     
    duration = Duration.ofHours(2);
    System.out.println(duration.toString());     //PT2H
     
    duration = Duration.between(Instant.now(), Instant.now().plus(Duration.ofMinutes(10)));
    System.out.println(duration.toString());  //PT10M
    

    Duration处理的是小单位的时间区间,比如 毫秒,秒,分钟和小时。更加适合和机器交互的场景。如果在和人进行交互的场景下,可以使用 Period

    Period

    Period 代表更大的时间间隔。

    Period period = Period.ofDays(6);
    System.out.println(period.toString());    //P6D
     
    period = Period.ofMonths(6);
    System.out.println(period.toString());    //P6M
     
    period = Period.between(LocalDate.now(),
                LocalDate.now().plusDays(60));
    System.out.println(period.toString());   //P1M30D
    

    添加新的枚举类

    在 Java 8 中添加了一些新的枚举类,我们就拿 DayOfWeek 类来距离。

    DayOfWeek

    //day-of-week to represent, from 1 (Monday) to 7 (Sunday)
    System.out.println(DayOfWeek.of(2));                    //TUESDAY
    
    DayOfWeek day = DayOfWeek.FRIDAY;
    System.out.println(day.getValue());                     //5
    
    localDate = LocalDate.now();
    System.out.println(localDate.with(DayOfWeek.MONDAY));  //2018-04-16  i.e. when was monday in current week ?
    

    其他的类还有 Month, MonthDay, Year, YearMonth, 当然还有更多。

    Date adjusters

    Date adjusters 表示日期管理员,这是一个实用的工具类。这个类的主要功能是用于解决这类问题的,“上个月的最后一天?”,“下一个工作日?” 或者 “下一个周四?”。

    LocalDate date = LocalDate.of(2018, Month.APRIL, 22);                     //Today
    
    LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
    System.out.println(endOfMonth.toString());                              //2018-04-30
    
    LocalDate nextTue = date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY));
    System.out.println(nextTue.toString());                                 //2018-04-24            
    

    创建 date 对象

    现在可以使用构造者模式来创建 date 对象。构造者模式能够以单独的部分来进行构造。这些方法都是以 "at" 作为方法前缀。

    //Builder pattern used to make date object
    OffsetDateTime date1 = Year.of(2018)
            .atMonth(Month.APRIL).atDay(22)
            .atTime(0, 0)
            .atOffset(ZoneOffset.of("+08:00"));
    System.out.println(date1);                                     //2018-04-22T00:00+08:00
    
    //factory method used to make date object
    OffsetDateTime date2 = OffsetDateTime.
            of(2018, 4, 22, 0, 0, 0, 0, ZoneOffset.of("+08:00"));
    System.out.println(date2);
    

    模拟系统时钟的新类

    Clock 类能够模拟系统时钟。这个有什么用呢?当我们在编写与时间有关的逻辑的时候,单元测试的时候,我们可能会需要将来的某个时间点,因此需要修改系统的时间然后重启使其生效。

    现在,有了 Clock 类,就不必这么做了。Clock 能够模拟系统时钟。

    Clock clock = Clock.systemDefaultZone();
    System.out.println(clock);                      //SystemClock[Asia/Shanghai]
    System.out.println(clock.instant().toString()); //2018-04-22T13:25:59.384Z
    System.out.println(clock.getZone());            //Asia/Shanghai
    
    Clock anotherClock = Clock.system(ZoneId.of("Europe/Tiraspol"));
    System.out.println(anotherClock);                       //SystemClock[Europe/Tiraspol]
    System.out.println(anotherClock.instant().toString());  //2018-04-22T13:25:59.397Z
    System.out.println(anotherClock.getZone());             //Europe/Tiraspol
    
    Clock forwardedClock  = Clock.tick(anotherClock, Duration.ofSeconds(600));
    System.out.println(forwardedClock.instant().toString());  //2018-04-22T13:20:00Z
    

    这里对这个 tick 方法说明一下,因为这个方法我看了半天都不懂这个方法到底想做什么。tick方法就是将时钟以给定的 Duration为间隔进行打点,然后找到最接近给定 Clock 的 Clock。哎说不清楚,举例子说明吧。

    假如你的时钟现在处于 10s 的状态。你给定的 Duration 为2s,那么就会从0s 开始以2s为间隔进行打点,0s,2s,4s,6s,8s 最近的就是8s 了,所有就会返回这个 Clock。如果你指定的是0.5s,那么就是0s,0.5s,1s,.....知道9.5s。

    格式化

    日期格式化主要通过2个类,DateTimeFormatterBuilderDateTimeFormatterDateTimeFormatterBuilder 类主要是提供构造者模式创建自定义的 DateTimeFormatter 类。

    DateTimeFormatterBuilder formatterBuilder = new DateTimeFormatterBuilder();
    formatterBuilder.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                    .appendLiteral("-")
                    .appendZoneOrOffsetId();
    DateTimeFormatter formatter = formatterBuilder.toFormatter();
    System.out.println(formatter.format(ZonedDateTime.now()));
    

    哎,感觉讲完这些还是需要实例才能弄明白,下面一篇写一点例子吧。

    欢迎关注我的微信公众号:java初学者的日常

    java初学者的日常

    相关文章

      网友评论

        本文标题:Java 8 | Date and Time

        本文链接:https://www.haomeiwen.com/subject/dgrclftx.html