由于历史原因,在之前的版本里无论Date还是Calendar都非常难用,尤其在涉及到日期计算方面,而且其中日期转换的类DateForamt还是非线程安全的。
也正因为难用,一般项目里面都引入第三方的类库操作时间,例如Joda-Time和apache-lang包的DateUtils类。
  基于上述种种原因,Java8新增了java.time包,其中包含了新的处理时间的类来解决上述问题。

1.主要类:

LocalDate、LocalTime、 Instant、 Duration 以及 Period

LocalDate和LocalTime及LocalDateTime

eg:

@Test
public void test8time() {
// LocalDate
// 创建LocalDate
LocalDate localDate1 = LocalDate.of(2018, 7, 26);
LocalDate localDate2 = LocalDate.now();
LocalDate localDate3 = LocalDate.parse("2014-03-18");
System.out.println(localDate1 + " " + localDate2 + " " + localDate3); int year = localDate1.getYear();
Month month = localDate1.getMonth();
int day = localDate1.getDayOfMonth();
DayOfWeek dow = localDate1.getDayOfWeek();
int len = localDate1.lengthOfMonth();
// 是否闰年
boolean leap = localDate1.isLeapYear(); System.out.println(year);
System.out.println(month);
System.out.println(day);
System.out.println(dow);
System.out.println(len);
System.out.println(leap); // 通过传递 TemporalField 来换取时间 类似于工厂模式
// ChronoField此枚举实现了TemporalField接口
int fieldYear = localDate1.get(ChronoField.YEAR);
int fieldMonth = localDate1.get(ChronoField.MONTH_OF_YEAR);
int fieldDay = localDate1.get(ChronoField.DAY_OF_MONTH);
System.out.println(fieldYear);
System.out.println(fieldMonth);
System.out.println(fieldDay);
// LocalTime
// 创建LocalTime
LocalTime time = LocalTime.of(11, 10, 20);
LocalTime time1 = LocalTime.now();
LocalTime time2 = LocalTime.parse("11:10:20");
System.out.println(time + " " + time1 + " " + time2);
System.out.println(String.join(" ", time.toString(), time1.toString(), time2.toString())); int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
System.out.println(hour);
System.out.println(minute);
System.out.println(second); int fieldHour = time.get(ChronoField.HOUR_OF_DAY);
int fieldMinute = time.get(ChronoField.MINUTE_OF_HOUR);
int fieldSecond = time.get(ChronoField.SECOND_OF_MINUTE);
System.out.println(fieldHour);
System.out.println(fieldMinute);
System.out.println(fieldSecond); // 合并时间 创建LocalDateTime
LocalDateTime ldt = LocalDateTime.of(localDate1, time);
System.out.println(ldt);
LocalDateTime ldt1 = LocalDateTime.now();
System.out.println(ldt1); LocalDate ld = ldt1.toLocalDate();
LocalTime lt = ldt1.toLocalTime();
System.out.println(ld);
System.out.println(lt);
}

Instant

@Test
public void testInstant() {
// Instant 是以Unix元年时间开始所经历的秒数进行计算
Instant instant = Instant.ofEpochSecond(1);
System.out.println(instant);
Instant instant1 = Instant.now();
System.out.println(instant1);
}

Duration和Period
Duration类主要用于以秒和纳秒衡量时间的长短。
Period类主要以年、月或者日的方式衡量时间长短。

@Test
public void testDp() {
LocalTime time1 = LocalTime.now();
LocalTime time2 = LocalTime.now();
LocalDateTime dateTime1 = LocalDateTime.now();
LocalDateTime dateTime2 = LocalDateTime.now();
Instant instant1 = Instant.now();
Instant instant2 = Instant.now();
Duration d1 = Duration.between(time1, time2);
Duration d2 = Duration.between(dateTime1, dateTime2);
Duration d3 = Duration.between(instant1, instant2); System.out.println(d1);
System.out.println(d2);
System.out.println(d3); // 创建
Duration threeMinutes = Duration.ofMinutes(3);
Duration threeMinutes1 = Duration.of(3, ChronoUnit.MINUTES);
Period tenDays = Period.ofDays(10);
Period threeWeeks = Period.ofWeeks(3);
Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1); System.out.println(threeMinutes);
System.out.println(threeMinutes1);
System.out.println(tenDays);
System.out.println(threeWeeks);
System.out.println(twoYearsSixMonthsOneDay);
}

2.对日期的操作

eg:

@Test
public void operaTime() {
// 直接操作
LocalDate date1 = LocalDate.of(2018, 7, 26);
LocalDate date2 = date1.withYear(2017);
LocalDate date3 = date2.withDayOfMonth(25);
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 4);
LocalDate date5 = date1.withYear(2017).withMonth(4).withDayOfMonth(25);
System.out.println(date4);
System.out.println(date5); // 相对操作
LocalDate date6 = LocalDate.of(2018, 7, 26);
LocalDate date7 = date6.plusWeeks(1);
LocalDate date8 = date7.minusYears(3);
LocalDate date9 = date8.plus(6, ChronoUnit.MONTHS);
LocalDate date10 = date6.plusWeeks(1).minusYears(3).plusMonths(6);
System.out.println(date9);
System.out.println(date10); // 使用 TemporalAdjuster 操作日期
LocalDate date11 = LocalDate.now().with(lastDayOfMonth());
System.out.println(date11); }

TemporalAdjuster接口里面的静态方法
dayOfWeekInMonth 创建一个新的日期,它的值为同一个月中每一周的第几天
firstDayOfMonth 创建一个新的日期,它的值为当月的第一天
firstDayOfNextMonth 创建一个新的日期,它的值为下月的第一天
firstDayOfNextYear 创建一个新的日期,它的值为明年的第一天
firstDayOfYear 创建一个新的日期,它的值为当年的第一天
firstInMonth 创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值
lastDayOfMonth 创建一个新的日期,它的值为当月的最后一天
lastDayOfNextMonth 创建一个新的日期,它的值为下月的最后一天
lastDayOfNextYear 创建一个新的日期,它的值为明年的最后一天
lastDayOfYear 创建一个新的日期,它的值为今年的最后一天
lastInMonth 创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值
next/previous 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期
nextOrSame/previousOrSame 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期,如果该日期已经符合要求,直接返回该对象

对日期的解析DateTimeFormatter

eg:

@Test
public void testFormat() {
LocalDate ld = LocalDate.now();
String ld1 = ld.format(DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(ld1); LocalDate ld2 = LocalDate.parse("20180726",
DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(ld2); LocalDateTime ld3 = LocalDateTime.now();
ZoneId bjZone = ZoneId.of("Asia/Shanghai");
// ZoneId zoneId = TimeZone.getDefault().toZoneId();
ZonedDateTime adt = ld.atStartOfDay(bjZone);
ZonedDateTime adt1 = ld3.atZone(bjZone);
Instant instant = Instant.now();
ZonedDateTime adt2 = instant.atZone(bjZone);
System.out.println(adt);
System.out.println(adt1);
System.out.println(adt2);
}

3.Date, LocalDate, LocalDateTime和Instant之间的相互转换

  Date类新增了from和toInstant两个方法实现和Instant之间的互转,在通过Instant这个桥梁转换成LocalDate和LocalDateTime。

@Test
public void testDate2Local() {
// Date转成LocalDateTime和LocalDate
Date date = new Date();
Instant instant = date.toInstant();
ZoneId zone = ZoneId.systemDefault();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
LocalDate localDate = localDateTime.toLocalDate();
System.out.println(localDate);
System.out.println(localDateTime); // LocalDate和LocalDateTime转成Date
LocalDateTime localDateTime1 = LocalDateTime.now();
ZonedDateTime zonedDateTime = localDateTime1.atZone(ZoneId.systemDefault());
Instant instant1 = zonedDateTime.toInstant();
Date date1 = Date.from(instant1);
System.out.println(date1); LocalDate localDate1 = LocalDate.now();
LocalDateTime localDateTime2 = localDate1.atStartOfDay();
ZonedDateTime zonedDateTime1 = localDateTime2.atZone(ZoneId.systemDefault());
Instant instant2 = zonedDateTime1.toInstant();
Date date2 = Date.from(instant2);
System.out.println(date2);
}

总结:

  新的API是时间处理变的简单,也解决了线程安全的问题,希望大家都能慢慢转过来。

参考:

《Java8实战》

Java8简明学习之新时间日期API的更多相关文章

  1. Java8新特性(三)——Optional类、接口方法与新时间日期API

    一.Optional容器类 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. 查看结构图可以看到有如下常用方法: of(T)—— ...

  2. 七、新时间日期 API

    一.使用 LocalDate. LocalTime. LocalDateTime LocalDate. LocalTime. LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO- ...

  3. 四、新时间日期API

    一.使用 LocalDate .LocalTime .LocalDateTime LocalDate.LocalTime.LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-86 ...

  4. JAVA 8 主要新特性 ----------------(七)新时间日期 API -----LocalDateTime

    一.LocalDateTime简介 二.实战讲解 LocalDateTime localDateMax = LocalDateTime.MAX; System.out.println("lo ...

  5. JAVA 8 主要新特性 ----------------(七)新时间日期 API -----LocalDate

    一.改版原因 1.老板的Date和Calander存在问题,日期操作名称混乱,有的在text下,有的在util下,包名混乱         2.Simple包混乱,致命错误线程不安全.        ...

  6. JAVA 8 主要新特性 ----------------(七)新时间日期 API ----- Duration “时间”间隔

    Duration:用于计算两个“时间”间隔 简介: 用法: 1.Zero常量 实例: Duration duration = Duration.ZERO; System.out.println(&qu ...

  7. JAVA 8 主要新特性 ----------------(七)新时间日期 API -----Instant 时间戳

    一.简介 用于“时间戳”的运算.它是以Unix元年(传统 的设定为UTC时区1970年1月1日午夜时分)开始 所经历的描述进行运算 二.文档介绍 1.now Instant instantNow = ...

  8. JAVA8学习——新的时间日期API&Java8总结

    JAVA8-时间日期API java8之前用过的时间日期类. Date Calendar SimpleDateFormat 有很多致命的问题. 1.没有时区概念 2.计算麻烦,实现困难 3.类是可变的 ...

  9. java8新特性——时间日期API

    传统的时间 API 存在线程安全的问题,在多线程开发中必须要上锁,所以 java8 现在为我们提供了一套全新的时间日期 API ,今天进来学习一下java8 的时间日期 API. 一.使用 Local ...

随机推荐

  1. 三,memcached服务的两种访问方式

    memcached有两种访问方式,分别是使用telnet访问和使用php访问. 1,使用telnet访问memcacehd 在命令提示行输入, (1)连接memcached指令:telnet 127. ...

  2. 2018年Android面试题含答案--适合中高级(下)

    这里是我整理出来的面试题,答案我花了很久的时间.加上我自己的理解整理出来的,作者不易,请谅解.有答案的的:https://xiaozhuanlan.com/topic/6132940875   1.A ...

  3. [Swift实际操作]七、常见概念-(1).范围Range、ClosedRange和NSRange的使用实际操作

    本文将为你解析区间的概念.在对字符串进行处理时,经常会使用到区间.例如获得字符串中从某个位置开始到另一个位置之间的内容. 首先导入需要使用到的框架 import Foundation 区间分为闭区间和 ...

  4. jQuery.cookie的使用指南

    一个轻量级的cookie 插件,可以读取.写入.删除 cookie. 配置 首先包含jQuery的库文件,在后面包含 jquery.cookie.js 的库文件. <script type=&q ...

  5. day 32 css后续补充以及js 简单入门

    前情提要: 利用html 和css ,js 模拟小米的官网(待做) 一:第一个sj利子 <!DOCTYPE html> <html lang="en"> & ...

  6. Java中equals,hashcode

         在Java语言中,Object对象中包含一个equals和hashCode方法,其中hashCode方法是由JVM本地代码(native code)实现的,返回值是一个有符号的32位整数,对 ...

  7. Android学习之一

  8. phpdocumentor生成代码注释文档(linux)

    1,默认安装lnmp环境(php7),默认pear安装 2,   pear channel-discover pear.phpdoc.org pear install phpdoc/phpDocume ...

  9. springboot-14-自定义properties文件值注入javaBean中

    被这个问题困扰了好几天.... 在spring中, 从资源文件向bean中注入值非常简单, 只需要properties文件被spring加载, 然后在被spring管理的类写响应的属性, 然后 @Va ...

  10. 自学C Primer Plus时还没想明白的问题

    2016年11月24日 1. 计算机中两个浮点数怎样进行加法运算.2. 为什么计算机在计算时存在损失精度的可能3. 无符号数和有符号数的运算是怎样的4. printf中使用格式控制符的截断问题,比如% ...