美文网首页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