本文翻译:梁开权
Java 8是如何处理时间及日期的
有人问学习一个新库的最佳途径是什么?其实就是就是在实际项目中那样去使用它。在一个真实的项目中会有各种各样的需求,这会促使开发人员去探索和研究这个新库。
简言之,只有任务本身才会真正促使你去探索及学习。java 8的新的日期及时间API也是一样。为了学习Java 8的这个新库,这里我创建了几个以任务为导向的例子。
我们先从一个简单的任务开始,比如说如何用Java 8的时间日期库来表示今天,接着再进一步生成一个带时间及时区的完整日期,然后再研究下如何完成一些更实际的任务。
比如说开发一个提醒类的应用,来找出距离一些特定日期比如生日,周日纪念日,下一个帐单日,下一个溢价日或者信用卡过期时间还有多少天。
如何在Java 8中获取当天的日期
Java 8中有一个叫LocalDate的类,它能用来表示今天的日期。这个类与java.util.Date略有不同,因为它只包含日期,没有时间。因此,如果你只需要表示日期而不包含时间,就可以使用它。
LocalDate today = LocalDate.now();
System.out.println("现在的本地时间是 : " + today);
输出 :
现在的本地时间是 : 2019-01-05
你可以看到它创建了今天的日期却不包含时间信息。它还将日期格式化完了再输出出来,不像之前的Date类那样,打印出来的数据都是未经格式化的。
如何在Java 8中获取当前的年月日
LocalDate类中提供了一些很方便的方法可以用于提取出年月日以及其它的日期属性。使用这些方法,你可以获取到任何你所需要的日期属性,而不再需要使用java.util.Calendar这样的类了:
LocalDate today = LocalDate.now();
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();
System.out.printf("年: %d 月 : %d 日 : %d ", year, month, day);
输出:
年: 2019 月: 01 日: 05
可以看到,在Java 8中获取年月信息非常简单,只需使用对应的getter方法就好了,无需记忆,非常直观。你可以拿它和Java中老的获取当前年月日的写法进行一下比较。
在Java 8中如何获取某个特定的日期
在第一个例子中,我们看到通过静态方法now()来生成当天日期是非常简单的,不过通过另一个十分有用的工厂方法LocalDate.of(),则可以创建出任意一个日期,它接受年月日的参数,然后返回一个等价的LocalDate实例。
关于这个方法还有一个好消息就是它没有再犯之前API中的错,比方说,年只能从1900年开始,月必须从0开始,等等。这里的日期你写什么就是什么,比如说,下面这个例子中它代表的就是4月1日,没有什么隐藏逻辑。
LocalDate dateOfBirth = LocalDate.of(2018, 04, 01);
System.out.println("你的生日是 : " + dateOfBirth);
输出 :
你的生日是 : 2018-04-01
可以看出,创建出来的日期就是我们所写的那样,2014年1月14日。
在Java 8中如何检查两个日期是否相等
如果说起现实中实际的处理时间及日期的任务,有一个常见的就是要检查两个日期是否相等。你可能经常会碰到要判断今天是不是某个特殊的日子,比如生日啊,周年纪念日啊,或者假期之类。有的时候,会给你一个日期,让你检查它是不是某个日子比方说假日。
下面这个例子将会帮助你在Java 8中完成这类任务。
正如你所想的那样,LocalDate重写了equals方法来进行日期的比较,如下所示:
LocalDate date1 = LocalDate.of(2018, 04, 01);
LocalDate today = LocalDate.now();
System.out.println("date1和今天是同一天吗?:"+ date1.equals(today));
输出:
date1和今天是同一天吗?true
在本例中我们比较的两个日期是相等的。同时,如果在代码中你拿到了一个格式化好的日期串,你得先将它解析成日期然后才能比较。你可以将这个例子与Java之前比较日期的方式进行下比较,你会发现它真是爽多了。
在Java 8中如何检查重复事件
在Java中还有一个与时间日期相关的实际任务就是检查重复事件,比如说每月的帐单日,结婚纪念日,每月还款日或者是每年交保险费的日子。
如果你在一家保险公司工作的话,那么肯定会有这么一个模块,会去给用户发送生日祝福并且在每一个重要的假日给他们捎去问候,比如说圣诞节,感恩节,在印度则可能是万灯节(Deepawali)。
如何在Java中判断是否是某个节日或者重复事件?使用MonthDay类。这个类由月日组合,不包含年信息,也就是说你可以用它来代表每年重复出现的一些日子。当然也有一些别的组合,比如说YearMonth类。它和新的时间日期库中的其它类一样也都是不可变且线程安全的,并且它还是一个值类(value class)。
我们通过一个例子来看下如何使用MonthDay来检查某个重复的日期:
LocalDate dateOfBirth = LocalDate.of(2018, 04, 01);
MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());
MonthDay currentMonthDay = MonthDay.from(today);
System.out.println("今天是4月1日吗?" + currentMonthDay.equals(birthday));
输出:
今天是4月1日吗?false
虽然年不同,但今天就是生日的那天,所以在输出那里你会看到一条生日祝福。你可以调整下系统的时间再运行下这个程序看看它是否能提醒你下一个生日是什么时候,你还可以试着用你的下一个生日来编写一个JUnit单元测试看看代码能否正确运行。
如何在Java 8中获取当前时间
这与第一个例子中获取当前日期非常相似。这次我们用的是一个叫LocalTime的类,它是没有日期的时间,与LocalDate是近亲。这里你也可以用静态工厂方法now()来获取当前时间。
默认的格式是hh:mm:ss:nnn,这里的nnn是纳秒。可以和Java 8以前如何获取当前时间做一下比较。
LocalTime time = LocalTime.now();
System.out.println("当前时间是 : " + time);
输出:
当前时间是 : 20:12:23.501
可以看到,当前时间是不包含日期的,因为LocalTime只有时间,没有日期。
更多的内容我们可以在下个章节继续探讨
想获取更多技术视频,请前往叩丁狼官网:http://www.wolfcode.cn/openClassWeb_listDetail.html