Java8新特性的功能已经更新了很多篇幅了,今天重点讲解时间日期库中DateTime相关处理。一样的,若是你如今依旧在项目中使用传统Date、Calendar和SimpleDateFormat等API来处理日期相关操做,这篇文章你必定不要错过。来刷新你的知识库吧!java
Java对日期、日历及时间的处理一直以来都饱受诟病,好比java.util.Date和java.util.Calendar类易用性差,不支持时区,非线程安全;还有用于格式化日期的类DateFormat也是非线程安全的等问题。api
Java8引入的新的一系列API,对时间日期的处理提供了更好的支持,清楚的定义了时间日期的一些概念,好比说,瞬时时间(Instant),持续时间(duration),日期(date),时间(time),时区(time-zone)以及时间段(Period)。安全
同时,借鉴了Joda库的一些优势,好比将人和机器对时间日期的理解区分开的。微信
新的时间日期API核心位于java.time内,另外也在java.time.chrono,java.time.format,java.time.temporal和java.time.zone有相关的API,但使用频次较少。学习
Java8经常使用的日期和时间类包含LocalDate、LocalTime、Instant、Duration、Period、LocalDateTime以及ZonedDateTime等。spa
另外,还有新的日期解析格式化类DateTimeFormatter。线程
学习最佳的途径就是去实践它,如今咱们示例的形式来说每一个知识点进行讲解。3d
LocalDate类内只包含日期,不包含具体时间。只须要表示日期而不包含时间,就可使用它。code
// 只获取日期
LocalDate today = LocalDate.now();
System.out.println(today);
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();
System.out.printf("Year : %d Month : %d day : %d \t %n", year, month, day);
复制代码
同时,还能够经过LocalDate获取日期是月份的第几天、周的第几天,月份的天数,是否为闰年等。看下面的代码是否是很是方便。orm
LocalDate today = LocalDate.now();
// 月份中的第几天
int dayOfMonth = today.getDayOfMonth();
// 一周的第几天
DayOfWeek dayOfWeek = today.getDayOfWeek();
// 月份的天数
int length = today.lengthOfMonth();
// 是否为闰年
boolean leapYear = today.isLeapYear();复制代码
上面经过now获取LocalDate对象,也能够经过静态方法of()或parse建立任意一个日期。不再用像以前同样年只能从1900年开始,月必须从0开始等。
LocalDate oneDay = LocalDate.of(2019,10,1);
System.out.println(oneDay);
LocalDate parseDay = LocalDate.parse("2019-10-01");
System.out.println(parseDay);复制代码
打印结果:2019-10-01。
LocalDate重写了equals方法,让日期的比较也变得简单了。
// 定义任意日期
LocalDate oneDay = LocalDate.of(2019, 10, 1);
System.out.println(oneDay);
// 定义任意比较
LocalDate anyDay = LocalDate.of(2019, 10, 1);
System.out.println(oneDay.equals(anyDay));复制代码
同时,针对日期还可延伸出MonthDay或YearMonth类,顾名思义,只包含月天或年月。一样适用于equals方法来比较。
另外使用before和after能够比较两个日期先后时间。
boolean notBefore = LocalDate.parse("2019-10-01").isBefore(LocalDate.parse("2019-10-02"));
boolean isAfter = LocalDate.parse("2019-10-01").isAfter(LocalDate.parse("2019-10-02"));复制代码
对日期进行前一天后一天或前一个月的加减也变得十分方便。
LocalDate tomorrowDay = LocalDate.now().plusDays(1);
LocalDate nextMonth = LocalDate.now().plusMonths(1);复制代码
还有,咱们在实战的时候每每要获取某一天的开始时间和当天所在月的第一天等。
LocalDate.now().atStartOfDay();
LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());复制代码
LocalTime和LocalDate相似,区别在于LocalDate不包含具体时间,而LocalTime包含具体时间。一样可使用now或of方法来得到对象。
LocalTime localTime = LocalTime.now();
LocalTime oneTime = LocalTime.of(10,10,10);复制代码
LocalDate相似它也拥有parse、isBefore、获取时间单元等方法,就再也不赘述。
须要注意的是,LocalTime得到的时间格式为:11:41:58.904。也就是,HH:mm:ss.nnn,这里nnn是纳秒。
还有一个在实战中查询日期区间时咱们常常定义的“23:59:59.99”常量不再用本身定义了。
// 23:59:59.999999999
LocalTime maxTime = LocalTime.MAX;
// 00:00
LocalTime minTime = LocalTime.MIN;复制代码
LocalDateTime表示日期和时间组合。能够经过of()方法直接建立,也能够调用LocalDate的atTime()方法或LocalTime的atDate()方法将LocalDate或LocalTime合并成一个LocalDateTime。
建立时间示例:
LocalDateTime now = LocalDateTime.now();
LocalDateTime oneTime = LocalDateTime.of(2019,10,14,10,12,12);
// 拼接日期
LocalTime.now().atDate(LocalDate.now());复制代码
LocalDateTime与LocalDate和LocalTime之间能够相互转化。其余日期增减等操做与上面的相似。
Instant用于一个时间戳,与System.currentTimeMillis()相似,但Instant能够精确到纳秒(Nano-Second)。
Instant除了可使用now()方法建立,还能够经过ofEpochSecond方法建立。
Instant now = Instant.now();
Instant.ofEpochSecond(365 * 24 * 60, 100);复制代码
其中ofEpochSecond第一个参数表示秒,第二个参数表示纳秒。总体表示:从1970-01-01 00:00:00开始后的365天100纳秒的时间点。
Duration的内部实现与Instant相似,但Duration表示时间段,经过between方法建立。
LocalDateTime from = LocalDateTime.now();
LocalDateTime to = LocalDateTime.now().plusDays(1);
Duration duration = Duration.between(from, to);
// 区间统计换算
// 总天数
long days = duration.toDays();
// 小时数
long hours = duration.toHours();
// 分钟数
long minutes = duration.toMinutes();
// 秒数
long seconds = duration.getSeconds();
// 毫秒数
long milliSeconds = duration.toMillis();
// 纳秒数
long nanoSeconds = duration.toNanos();复制代码
Duration对象还能够经过of()方法建立,该方法参数为时间段长度和时间单位。
// 7天
Duration duration1 = Duration.of(7, ChronoUnit.DAYS);
// 60秒
Duration duration2 = Duration.of(60, ChronoUnit.SECONDS);复制代码
Period与Duration相似,获取一个时间段,只不过单位为年月日,也能够经过of方法和between方法建立,between方法接收的参数为LocalDate。
Period period = Period.of(1, 10, 25);
Period period1 = Period.between(LocalDate.now(), LocalDate.now().plusYears(1));复制代码
ZonedDateTime类,用于处理带时区的日期和时间。ZoneId表示不一样的时区。大约有40不一样的时区。
获取全部时区集合:
Set allZoneIds = ZoneId.getAvailableZoneIds();复制代码
建立时区:
ZoneId zoneId = ZoneId.of("Asia/Shanghai");复制代码
把LocalDateTime转换成特定的时区:
ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.now(), zoneId);
复制代码
另外和时区一块儿使用的类是OffsetDateTime类,OffsetDateTime是不变的,表示date-time偏移,存储全部日期和时间字段,精确至纳秒,从UTC/Greenwich计算偏移。
Java8对日期的格式化操做很是简单,首先看到上面的类大多都提供了parse方法,能够直接经过解析字符串获得对应的对象。
而日期和时间的格式化可经过LocalDateTime的format方法进行格式化。
LocalDateTime dateTime = LocalDateTime.now();
String str = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(str);
str = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(str);复制代码
可使用DateTimeFormatter预置的格式,也能够经过DateTimeFormatter.ofPattern方法来指定格式。
Java8中关于时间日期的API有如下关键点:
好了,关于Java8新特性的时间日期功能就将到这里,用起来是否是简单明快多了,赶忙在项目中练练手吧。
原文连接:《Java8新特性时间日期库DateTime API及示例》