深入学习 Java 8 全新日期时间库 java.time(一)

一、简介

Java 1.8 引入了全新的日期时间库 java.time,在介绍新的日期时间库之前,先了解下原来的日期时间工具的诟病。

在 Java SE 8 前,日期时间工具库在 java.util 包中,包括:

  • java.util.Date:表示日期和时间
  • java.util.Calendar以及其实现子类:表示各种日历系统,常用的是格林威治日历java.util.GregorianCalendar
  • java.util.TimeZone以及其实现子类:表示时区偏移量和夏令时

以及辅助其进行格式化和解析的工具库在 java.text 包中,包括:

  • java.text.DateFormat:格式化日期时间和解析日期时间的工具抽象类
    • java.text.SimpleDateFormatDateDateFormat的实现

下面简要总结一下原有的日期时间在设计上的瑕疵和被开发者无限吐槽的诟病:

  • 从以上的api上看,Java 8 之前的日期时间工具库概念较为集中,缺乏年、月、日、时间、星期的单独抽象;
  • Date日期时间类既描述日期又描述时间,且Date不仅在 java.util 包中存在,在 java.sql 中也存在,名称重复,很容易导致bug发生;
  • api在设计上比较晦涩,难用,难以用人们自然的思维去理解日期时间。年月日需要从Calendar中获取;
  • 最被开发者抱怨的是类型不安全Calendar类中全局属性是可变的,在多线程访问时,会存在线程安全问题。SimpleDateFormat格式化和解析日期,需要使用年月日时分秒,所以持有了Calendar属性,导致其也是非线程安全;

二、入门

我们使用新的日期时间库 java.time首先要接触到的就是 LocalDateLocalTimeLocalDateTime,顾名思义,其意思就是本地日期、本地时间 和 本地日期时间。

LocalDate 只包含日期,例如:“2007-12-03”,而 LocalTime 则只包含时间其精确到纳秒值,例如:“12:14:23.267”。相对的 LocalDateTime其实就是LocalDateLocalTime 的结合体,其包含了日期和时间。

java.time库利用【?】工厂模式为我们提供了创建这些日期时间的工厂方法,主要分为四类:

  • now:根据当前的日期时间来生成,同时我们也可以指定相应的时钟【Clock】或时区ID【ZoneId】,否则就按照本地的时钟或时区生成
  • parse:通过指定的日期时间的字符串生成,同时我们也可以指定字符串的格式
  • of:通过指定生成时间日期的详细信息生成
  • from:相对较为高级了,我们若了解了架构层次其实也不复杂,简而言之就是通过其它日期时间对象来生成当前类型的时间对象

我们以 LocalDate为例简单的演示一下:

LocalDate date01 = LocalDate.now(); // 2019-08-09
LocalDate date02 = LocalDate.parse("2022-05-02"); // 2022-05-02
LocalDate date03 = LocalDate.of(1995, Month.JULY, 15); // 1995-07-15
LocalDateTime dateTime = LocalDateTime.of(1989, 12, 12, 5, 28);
LocalDate date04 = LocalDate.from(dateTime); // 1989-12-12

LocalDateLocalTimeLocalDateTime 这三者也都提供了相互转换的方法:

  • LocalDateLocalDateTime
    • atStartOfDay:将此日期和午夜时间结合起来创建LocalDateTime实例
    • atTime:通过指定详细的时间参数来生成LocalDateTime实例
  • LocalTimeLocalDateTime
    • atDate:将时间与指定的日期日期结合起来成LocalDateTime实例
  • LocalDateTimeLocalDateLocalTime
    • toLocalDate:将LocalDateTime转变成LocalDate
    • toLocalTime:将LocalDateTime转变成LocalTime

我们可以利用对应的**get*()**方法拿到更加详细的信息:

LocalDateTime dateTime = LocalDateTime.now();
int year = dateTime.getYear();
Month month = dateTime.getMonth();
int monthValue = dateTime.getMonthValue();
int dayOfYear = dateTime.getDayOfYear();
int dayOfMoth = dateTime.getDayOfMonth();
DayOfWeek dayOfWeek = dateTime.getDayOfWeek();
int hour = dateTime.getHour();
int minute = dateTime.getMinute();
int second = dateTime.getSecond();
int nano = dateTime.getNano();// 纳秒

相对更加高级点的获取方法:

  • int get(TemporalField field):从此日期时间中获取指定字段的int值。
  • long getLong(TemporalField field):从此日期时间中获取指定字段的long值。

TemporalField是一个接口,定义了如何访问 temporal 对象某个字段的值,此处不详细解释 temporal ,其大概意思就是所有时间日期的顶头上司。只有一个枚举 java.time.temporal.ChronoField 实现了此TemporalField接口。使用起来更加的整洁易懂,但是若获取当前对象不支持的某个字段则会抛出 UnsupportedTemporalTypeException 异常。

dateTime.get(ChronoField.MONTH_OF_YEAR);
dateTime.get(ChronoField.DAY_OF_YEAR);
dateTime.get(ChronoField.DAY_OF_MONTH);
dateTime.get(ChronoField.DAY_OF_WEEK);

同样的类库也为我们提供了**minus*** 、plus*with* 方法来对应进行 增、减 和 修改 相关参数信息的操作:

LocalDate date = LocalDate.of(2025, 6, 8);
LocalTime time = LocalTime.of(7, 25, 38);
LocalDateTime dateTime = LocalDateTime.of(date, time); // 2025-06-08T07:25:38
LocalDateTime temp1 = dateTime.minusYears(3); // 2022-06-08T07:25:38
LocalDateTime temp2 = dateTime.minusMonths(16); // 2024-02-08T07:25:38
LocalDateTime temp3 = dateTime.minusDays(25); // 2025-05-14T07:25:38
LocalDateTime temp4 = dateTime.plusHours(12); // 2025-06-08T19:25:38
LocalDateTime temp5 = dateTime.plusMinutes(12); // 2025-06-08T07:37:38
LocalDateTime temp6 = dateTime.withSecond(3); // 2025-06-08T07:25:03

相对更加高级点的方法:

  • minus(long amountToSubtract, TemporalUnit unit)
  • minus(TemporalAmount amountToSubtract)
  • plus(long amountToAdd, TemporalUnit unit)
  • plus(TemporalAmount amountToAdd)
  • with(TemporalAdjuster adjuster)
  • with(TemporalField field, long newValue)
  • LocalDateTime
    • LocalDateTime truncatedTo(TemporalUnit unit)
  • LocalTime
    • LocalTime truncatedTo(TemporalUnit unit)

由于这些方法设计的面相对广了点,后面我们在对其进行详细的解释!如果想提前了解相关信息可以直接访问 深入学习 Java 8 全新日期时间库 java.time(三)

类库也为我们提供了比较的方法:【字面意思很好理解】

  • boolean isAfter(ChronoLocalDateTime<?> other)
  • boolean isBefore(ChronoLocalDateTime<?> other)
  • boolean isEqual(ChronoLocalDateTime<?> other)

其它常用方法还有:

  • Temporal adjustInto(Temporal temporal):调整指定的temporal【时态】对象,使其具有与此对象相同的日期。【TemporalAdjuster接口的实现】
  • String format(DateTimeFormatter formatter):使用指定的格式化程序格式化此日期。
  • boolean isLeapYear():根据ISO标准的日历系统规则,检查该年是否是闰年。
  • boolean isSupported(TemporalField field):检查指定的 field 是否支持。
  • boolean isSupported(TemporalUnit unit):检查指定的 unit 是否支持。

赞赏

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值