JDK8新特性:日期时间相关API

JDK8新特性:日期时间相关API


旧版日期时间API存在的问题:

  • 1.设计很差:在 java.tilogjava sq| 的包中都有日期类,java.util.Date同时包含日期和时间,而 java.sql.Date 仅。包含日期。此外用于格式化和解析的类在 java.text 包中定义。
  • 2.非线程安全:java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
  • 3.时区处理麻烦:日期类并不提供国际化,没有时区支持。因此ava引入了 java.util.Calendarjava.util.TimeZone 类, 但他们同样存在上述所有的问题。

新日期时间API介绍

JDK 8中增加了一套全新的日期时间API,这套API设计合理,是线程安全的。

  • java.time - 包含值对象的基础包
  • java.time.chrono - 提供不同日历系统的访问
  • java.time.format - 格式化和解析时间和日期
  • java.time.temporal - 包含底层框架和扩展特性
  • java.time.zone - 包含时区支持的类

新的日期及时间API位于java.time包中,下面是一些关键类:

  • LocalDate:表示日期,包含年月日.格式为2019-10-16
  • LocalTime:表示时间,包含时分秒,格式为16:38:54.158549300
  • LocalDateTime:表示日期时间,包含年月日,时分秒,格式为2018-09-06T15:33:56.750
  • DateTimeFormatter:日期时间格式化类。
  • Instant:时间戳,表示一个特定的时间瞬间。
  • Duration:用于计算2个时间(LocalTime, 时分秒)的距离
  • Period:用于计算2个日期(LocalDate, 年月日)的距离
  • zonedDaterime:包含时区的时间

Java中使用的历法是ISO 8601日历系统,它是世界民用历法,也就是我们所说的公历。平年有365天.闰年是366天。此外ava 8还提供了4套其他历法,分别是:

  • ThaiBuddhistDate: 泰国佛教历
  • MinguoDate: 中华民国历
  • JapaneseDate:日本历
  • HijrahDate: 伊斯兰历

LocalDateTime、LocalDate、LocalTime常用方法

LocalDateTime = LocalDate + LocalTime

(1.)获取默认时区的当前时间
LocalDate localdate  = LocalDate.now();  --获取时间:年月日
LocalTime localtime  = LocalTime.now();  --获取时间:时分秒
LocalDateTime localdatetime  = LocalDateTime.now();  --获取时间:年月日时分秒

--结果:
localdate = 2020-06-16
localtime = 17:35:13.788
localdatetime = 2020-06-16T17:35:13.789

(2)指定具体的日期时间
LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30); -- 年月日时分秒
LocalDate date = LocalDate.of(2089, 12, 25); -- 年月日
LocalTime time1 = LocalTime.of(12, 30); -- 时分
LocalTime time2 = LocalTime.of(12, 30, 30); -- 时分秒
LocalTime time3 = LocalTime.of(12, 30, 30, 150); -- 时分秒纳秒

-- 结果
dateTime:2089-12-25T12:30:30
date:2089-12-25
time1:12:30
time2:12:30:30
time3:12:30:30.000000150

(3)获取具体的年月日时分秒、星期、天数等

这里为 LocalDateLocalTime 分开使用,也可以直接使用 LocalDateTime

LocalDate of = LocalDate.now();
System.out.println("年 = " + of.getYear());
System.out.println("月(英文) = " + of.getMonth());
System.out.println("月(数字) = " + of.getMonthValue());
System.out.println("这个月的第几天 = " + of.getDayOfMonth());
System.out.println("一年中的第几天 = " + of.getDayOfYear());
System.out.println("星期 = " + of.getDayOfWeek());

LocalTime nowTime = LocalTime.now();
System.out.println("时:" + nowTime.getHour());
System.out.println("分:" + nowTime.getMinute());
System.out.println("秒:" + nowTime.getSecond());
System.out.println("纳秒:" + nowTime.getNano());

(4)日期大小判断

这里的 isBeforeisAfter 比较都是后一个减去前一个,如果后面一个大,返回的是正数,否则是负数

LocalDate date1 = LocalDate.of(2020, 11, 30);
LocalDate date2 = LocalDate.of(2089, 12, 25);

System.out.println(date1.isBefore(date2));
System.out.println(date1.isAfter(date2));
System.out.println(date1.equals(date2));
System.out.println(date.isLeapYear()); -- 是否是闰年

(5)某个月或者某年有多少天
System.out.println(date1.lengthOfMonth()); -- 判断这个月有多少天
System.out.println(date1.lengthOfYear()); -- 判断年份有多少天

(6)直接修改、增加、减少年月日时分秒
-- 修改
LocalDateTime dateTime1 = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
System.out.println("设置年份:" + dateTime1.withYear(1991));
System.out.println("设置月份:" + dateTime1.withMonth(5));
System.out.println("设置小时:" + dateTime1.withHour(3));
System.out.println("设置分钟:" + dateTime1.withMinute(25));
System.out.println("设置秒:" + dateTime1.withSecond(26));
System.out.println("设置这个月的第多少天:" + dateTime1.withDayOfMonth(20));
System.out.println("设置这一年的第多少天:" + dateTime1.withDayOfYear(100));

-- 增加
System.out.println("增加年:" + dateTime1.plusYears(3));
System.out.println("增加月:" + dateTime1.plusMonths(5));
System.out.println("增加天:" + dateTime1.plusDays(3));
System.out.println("增加小时:" + dateTime1.plusHours(2));
System.out.println("增加分钟:" + dateTime1.plusMinutes(26));
System.out.println("增加秒:" + dateTime1.plusSeconds(20));

-- 减少
System.out.println("减少年:" + dateTime1.minusYears(3));
System.out.println("减少月:" + dateTime1.minusMonths(5));
System.out.println("减少天:" + dateTime1.minusDays(3));
System.out.println("减少小时:" + dateTime1.minusHours(2));
System.out.println("减少分钟:" + dateTime1.minusMinutes(26));
System.out.println("减少秒:" + dateTime1.minusSeconds(20));

(7)时间类型转换
LocalDateTime dateTime1 = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
LocalDate date = LocalDate.of(2089, 12, 25);
LocalTime time= LocalTime.of(12, 30, 30);

System.out.println(dateTime1.toLocalTime()); -- LocalDateTime转LocalTime
System.out.println(dateTime1.toLocalDate()); -- LocalDateTime转LocalDate
System.out.println(date.atTime(time)); -- LocalDate和LocalTime转LocalDateTime
System.out.println(time.atDate(date)); -- LocalDate和LocalTime转LocalDateTime

-- 结果
12:30:30
2089-12-25
2089-12-25T12:30:30
2089-12-25T12:30:30

日期解析和格式化:DateTimerFormatter

LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

-- 正反都能调用format方法
String date1 = dateTime.format(dtf);
System.out.println(date1);
String date2 = dtf.format(dateTime);
System.out.println(date2);

-- 结果
2089-12-25 12:30:30
2089-12-25 12:30:30

计算日期时间差 Duration 和 Period

  • Duration
LocalDateTime today = LocalDateTime.now();
LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30);

Duration duration = Duration.between(today, dateTime); 
System.out.println(duration.toDays());    -- 相差的天数
System.out.println(duration.toHours());   -- 相差的小时数
System.out.println(duration.toMinutes()); -- 相差的分钟数
System.out.println(duration.toMillis());  -- 相差的毫秒数
System.out.println(duration.toNanos());   -- 相差的纳秒数
  • Period
LocalDate today = LocalDate.now();
LocalDate date = LocalDate.of(2089, 12, 25);

Period period = Period.between(today, date);
System.out.println(period.getYears());  -- 相差多少年
System.out.println(period.getMonths()); -- 相差多少月
System.out.println(period.getDays());   -- 相差多少天

时间调整器:TemporalAdjuster 和 TemporalAdjusters

TemporalAdjuster 是函数式接口,可自定义调整;
TemporalAdjusters 是针对 TemporalAdjuster 的工具类,内置了很多方法
在这里插入图片描述


例子:

-- 调整到下一年的第一天
LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
LocalDateTime with = dateTime.with(TemporalAdjusters.firstDayOfNextYear());
System.out.println("with = " + with);

-- 结果
with = 2090-01-01T12:30:30

时间戳:Instant

Instant instant = Instant.now(); -- 得到当前时间到 1970-01-01 00:00:00 的毫秒值
System.out.println(instant);
System.out.println("秒数:" + instant .getEpochSecond());
System.out.println("毫秒数:" + instant .toEpochMilli());

这里的 Instant.now() 方法默认使用UTC时间,而不是系统默认时间。点进源码即可看到


时区相关:ZoneID、ZonedDateTime

--获取世界各个地方的时区集合
ZoneId.getAvailableZoneIds().forEach(System.out::println);

ZonedDateTime now = ZonedDateTime.now();-- 系统默认时区
ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());-- 标准时区 UTC
ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));--通过ZoneId指定时区
System.out.println("now = " + now);
System.out.println("now1 = " + now1);
System.out.println("now2 = " + now2);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章