首页 > 技术文章 > 技术文章精译 >

Java 8 时间日期库使用示例(二)

更新时间:2020-06-10 | 阅读量(1,379)

>本文翻译:梁开权 在上一个章节中我们使用Java8提供的时间日期库,能更加便捷和灵活的操作时间日期,本章节我们将接着之前的内容继续跟大家分享Java8的时间日期库 ###如何增加时间里面的小时数 很多时候我们需要增加小时,分或者秒来计算出将来的时间。Java 8不仅提供了不可变且线程安全的类,它还提供了一些更方便的方法譬如plusHours()来替换原来的add()方法。 顺便说一下,这些方法返回的是一个新的LocalTime实例的引用,因为LocalTime是不可变的,可别忘了存储好这个新的引用。 >LocalTime time = LocalTime.now(); LocalTime newTime = time.plusHours(2); // 加2个小时 System.out.println("两个小时后是 : " + newTime); 输出 : 两个小时后是 : 22:12:23.501 可以看到当前时间2小时后是22:12:23.501。现在你可以将它和Java中增加或者减少小时的老的方式进行下比较。一看便知哪种方式更好 ###如何获取1周后的日期 这与前一个获取2小时后的时间的例子类似,这里我们将学会如何获取到1周后的日期。LocalDate是用来表示无时间的日期的,它有一个plus()方法可以用来增加日,星期,或者月,ChronoUnit则用来表示这个时间单位。 由于LocalDate也是不可变的,因此任何修改操作都会返回一个新的实例,因此别忘了保存起来。 >LocalDate today = LocalDate.now(); LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); System.out.println("今天是 : " + today); System.out.println("一个星期后是 : " + nextWeek); 输出: 今天是 : 2018-04-01 一个星期后是 : 2018-04-08 可以看到7天也就是一周后的日期是什么。你可以用这个方法来增加一个月,一年,一小时,一分钟,甚至是十年,查看下Java API中的ChronoUnit类来获取更多选项。 ###一年前后的日期 这是上个例子的续集。上例中,我们学习了如何使用LocalDate的plus()方法来给日期增加日,周或者月,现在我们来学习下如何用minus()方法来找出一年前的那天。 >LocalDate previousYear = today.minus(1, ChronoUnit.YEARS); System.out.println("一年前是 : " + previousYear); LocalDate nextYear = today.plus(1, YEARS); System.out.println("一年后是 : " + nextYear); 输出: 一年前是 : 2017-04-01 一年后是 : 2019-04-01 可以看到现在一共有两年,一个是2017年,一个是2019年,分别是2018的前后那年。 ###在Java 8中使用时钟 Java 8中自带了一个Clock类,你可以用它来获取某个时区下当前的瞬时时间,日期或者时间。 可以用Clock来替代System.currentTimeInMillis()与 TimeZone.getDefault()方法。 >// 返回你当前系统中的世界标准时间. Clock clock = Clock.systemUTC(); System.out.println("Clock : " + clock); // 返回你当前系统中带有时区的时间 Clock.systemDefaultZone(); System.out.println("Clock : " + clock); 输出: Clock : SystemClock[Z] Clock : SystemClock[Asia/Shanghai] 在Java 8中,LocalDate类有一个isBefore()和isAfter()方法可以用来比较两个日期。 如果调用方法的那个日期比给定的日期要早的话,isBefore()方法会返回true。 >LocalDate tomorrow = LocalDate.of(2018, 4, 2); System.out.println("2018-04-02是未来的时间吗?" + tommorow.isAfter(today)); LocalDate yesterday = today.minus(1, DAYS); System.out.println("2018-03-31是过去的时间吗?" + yesterday.isBefore(today)); 输出: 2018-04-02是未来的时间吗?true 2018-03-31是过去的时间吗?true 可以看到在Java 8中进行日期比较非常简单。不需要再用像Calendar这样的另一个类来完成类似的任务了。 ###在Java 8中处理不同的时区 Java 8不仅将日期和时间进行了分离,同时还有时区。现在已经有好几组与时区相关的类了,比如ZonId代表的是某个特定的时区,而ZonedDateTime代表的是带时区的时间。它等同于Java 8以前的GregorianCalendar类。 使用这个类,你可以将本地时间转换成另一个时区中的对应时间,比如下面这个例子: >// 带有时区的日期和时间 ZoneId zId = ZoneId.of("GMT+8"); LocalDateTime localtDateAndTime = LocalDateTime.now(); ZonedDateTime bj = ZonedDateTime.of(localtDateAndTime, zId ); System.out.println("当前时区的日期和时间 : " + bj); 输出: 当前时区的日期和时间 : 2019-01-05T11:48:18.122+08:00[GMT+08:00] 可以拿它跟之前将本地时间转换成GMT时间的方式进行下比较。顺便说一下,正如Java 8以前那样,对应时区的那个文本可别弄错了,否则你会碰到这么一个异常: >Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: China/Bei_Jing at java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:272) at java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:227) at java.time.ZoneRegion.ofId(ZoneRegion.java:120) at java.time.ZoneId.of(ZoneId.java:403) at java.time.ZoneId.of(ZoneId.java:351) ###如何表示固定的日期 正如MonthDay表示的是某个重复出现的日子的,YearMonth又是另一个组合,它代表的是像信用卡还款日,定期存款到期日,options到期日这类的日期。 你可以用这个类来找出那个月有多少天,lengthOfMonth()这个方法返回的是这个YearMonth实例有多少天,这对于检查2月到底是28天还是29天可是非常有用的。 >YearMonth currentYearMonth = YearMonth.now(); System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth()); YearMonth creditCardExpiry = YearMonth.of(2018, Month.FEBRUARY); System.out.printf("你是信用卡在 %s 到期", creditCardExpiry); 输出: 当前年月的最后一天: 2019-01: 31 你是信用卡在 2018-02 到期 ###如何在Java 8中检查闰年 这并没什么复杂的,LocalDate类有一个isLeapYear()的方法能够返回当前LocalDate对应的那年是否是闰年。如果你还想重复造轮子的话,可以看下这段代码,这是纯用Java编写的判断某年是否是闰年的逻辑。 >System.out.print("今年2019是闰年?" + today.isLeapYear()); //直接判断是否闰年 输出: 今年2019是闰年?false 你可以多检查几年看看结果是否正确,最好写一个单元测试来对正常年份和闰年进行下测试。 ###两个日期之间包含多少天,多少个月 还有一个常见的任务就是计算两个给定的日期之间包含多少天,多少周或者多少年。你可以用java.time.Period类来完成这个功能。在下面这个例子中,我们将计算当前日期与将来的一个日期之前一共隔着几个月。 >LocalDate day = LocalDate.of(2018, Month.APRIL, 1); LocalDate today = LocalDate.now(); Period period = Period.between(day , today); System.out.println("2018年4月1日距离今天过去了多少个月: " + period.getMonths()); 输出: 2018年4月1日距离今天间隔多少个月: 9 可以看到,现在是2019月1月,而2018年愚人节是4月1日,因此中间隔着9个月。 ###带时区偏移量的日期与时间 在Java 8里面,你可以用ZoneOffset类来代表某个时区,比如印度是GMT或者UTC5:30,你可以使用它的静态方法ZoneOffset.of()方法来获取对应的时区。只要获取到了这个偏移量,你就可以拿LocalDateTime和这个偏移量创建出一个OffsetDateTime。 >LocalDateTime datetime = LocalDateTime.of(2018, Month.JANUARY, 14, 19, 30); ZoneOffset offset = ZoneOffset.of("+05:30"); OffsetDateTime date = OffsetDateTime.of(datetime, offset); System.out.println("带时区的日期和时间 : " + date); 输出: 带时区的日期和时间 : 2018-01-14T19:30+05:30 可以看到现在时间日期与时区是关联上了。还有一点就是,OffSetDateTime主要是给机器来理解的,如果是给人看的,可以使用ZoneDateTime类。 更多的内容我们可以在下个章节继续探讨 >想获取更多技术视频,请前往叩丁狼官网:[http://www.wolfcode.cn/openClassWeb_listDetail.html](http://www.wolfcode.cn/openClassWeb_listDetail.html)
叩丁狼学员采访 叩丁狼学员采访
叩丁狼头条 叩丁狼头条
叩丁狼在线课程 叩丁狼在线课程