前言
相比于大多数方法已经过时的Date类(
java.util
),使用JDK8推出的LocalDate系列的日期(以及时间)格式的工具类已经是大多数项目的选择。本篇文章将对LocalDate类的常用API以及这个日期类和Date类的区别进行介绍。希望本篇文章对各位读者能够有所帮助。
一、LocalDate类的简介
在JDK1.8中,新推出了LocalDate、LocatTime、LocalDateTime这三个日期时间相关的工具类,这三者分别涵盖了日期、时间、日期时间三个场景的信息,我们可以在实际应用中选择符合需要的类来进行使用。比如我想知道明天是几号,那很明显LocalDate
就可以满足我的需要。
二、常见API使用
(一)对象初始化
名称 | 作用 |
---|---|
now() | 获取包含默认时区的系统时钟的当前日期 |
now(Clock clock) | 提供LocalDate实例,该实例具有从指定时钟获得的当前日期 |
now(ZoneId zone) | 给出当前日期的LocalDate实例,该日期来自指定时区的系统时钟 |
of(int year, int month, int dayOfMonth) | 从给定的年、月、日中获得LocalDate实例,输入数据类型为int |
@Test
public void LocalDateTest(){
System.out.println(LocalDate.now());
// now 方法可以获取指定时区的日期
System.out.println(LocalDate.now(Clock.systemUTC()));
System.out.println(LocalDate.now(ZoneId.systemDefault()));
System.out.println(LocalDate.of(2022,3,3));
}
代码执行结果
(二)日期计算
名称 | 作用 |
---|---|
plusDays | 往后加n天,即获取n天后的日期 |
plusWeeks | 往后加n周,即获取n周后的日期 |
plusMonths | 往后加n月,即获取n月后的日期 |
plusYears | 往后加n年,即获取n年后的日期 |
minusDays | 往后减n天,即获取n天前的日期 |
... | minus也有减周、月、年相关的API这里就不写了 |
now | 获取当前日期 |
需要注意的是,日期计算后会生成新的日期,并不会影响原有的日期对象
@Test
public void LocalDateTest(){
//获取当前的日期
LocalDate currentDate = LocalDate.now();
LocalDate after3Date = currentDate.plusDays(3);
LocalDate after2Week = currentDate.plusWeeks(2);
LocalDate after1Month = currentDate.plusMonths(1);
LocalDate after1Year = currentDate.plusYears(1);
LocalDate before3Date = currentDate.minusDays(3);
System.out.println("当前的日期为:" + currentDate);
System.out.println("3天后的日期为:" + after3Date);
System.out.println("2周后的日期为:" + after2Week);
System.out.println("1个月的日期为:" + after1Month);
System.out.println("1年后的日期为:" + after1Year);
System.out.println("3天前的日期为:" + before3Date);
}
执行结果图
(三)日期比较
名称 | 作用 |
---|---|
isBefore | 判断当前日期对象是否在比较的日期对象之前 |
isAfter | 判断当前日期对象是否在比较的日期对象之后 |
isEqual | 判断当前日期对象是否与比较的日期对象(日期)相等 |
@Test
public void LocalDateTest(){
//获取当前的日期
LocalDate date1 = LocalDate.now();
LocalDate date2 = date1.plusDays(3);
System.out.println("date1 before date2 ? " + date1.isBefore(date2));
System.out.println("date1 after date2 ? " + date1.isAfter(date2));
System.out.println("date1 equal date2 ? " + date1.isEqual(date2));
}
执行结果
PS:其实这一块的话,java.utls.Date类也有类似的日期比较方法。从API的使用上来说,LocalDate和Date可能没有太大区别。从安全性来说,LocalDate要更胜利一筹。
(四)日期和字符串转化
LocalDate提供了丰富的API来满足我们对于不同日期格式的需求,最主要的核心方法就是format()
和parse()
,前者让我们可以实现日期的格式化,后者可以将字符串转为LocalDate
对象。
1、日期的格式化(LocalDate对象转字符串)
这个方法要求我们提供一个DateTimeFormatter
对象来作为格式标准。一般我们会使用DateTimeFormatter
对象的静态方法来定义日期格式。
@Test
public void LocalDateTest(){
//获取当前的日期
LocalDate date1 = LocalDate.now();
String formatDate = date1.format(DateTimeFormatter.ofPattern("MM dd / yyyy"));
System.out.println("格式化后的日期为:" + formatDate);
}
执行结果
2、字符串转日期
我们一般使用parse()
方法来进行字符串转日期的操作,需要注意的是parse()
方法默认是按照yyyy-MM-dd
的格式来将字符串转换为日期对象的,如果给定的字符串不是这个日期格式的,则需要手动指定解析的日期格式,否则程序会抛异常!!
@Test
public void LocalDateTest(){
// 默认转换的日期格式为 yyyy-MM-dd
LocalDate date = LocalDate.parse("2022-04-03");
System.out.println("date解析后的日期为:" + date);
LocalDate date2 = LocalDate.parse("2022/04/03",DateTimeFormatter.ofPattern("yyyy/MM/dd"));
System.out.println("date2解析后的日期为:" + date2);
}
代码执行结果
(五)获取对象上常用的属性
我们还可以便捷的在日期对象上面获取年月日等属性,方便后续程序的逻辑判断。常用的API如下:
名称 | 作用 |
---|---|
get(TemporalField field) | 获取指定字段的int值 |
getChronology() | 获取该日期格式,例如:ISO |
getDayOfMonth() | 获取一个月中的第几号,为int类型 |
getDayOfWeek() | 获取星期字段,返回DayOfWeek |
getDayOfYear() | 以 int 格式获取一年中的第几天。它可以返回从 1 到 365 或 366 (闰年)。 |
getEra() | 获取在此日期适用的时代。例如:"CE "从第一年开始,"BCE "从零年开始。 |
PS:LocalDate这套日期工具类体系中,会把月、日、年都看成是不同的对象,方便我们取出值后做进一步的日期比较或者计算。
@Test
public void LocalDateTest(){
LocalDate currentDate = LocalDate.now();
System.out.println("年份信息为:" + currentDate.getYear());
System.out.println("月份信息为:" + currentDate.getMonth().getValue());
System.out.println("日期信息为:" + currentDate.getDayOfMonth());
System.out.println("日期格式信息为:" + currentDate.getChronology());
System.out.println("年份格式信息(get写法)为:" + currentDate.get(ChronoField.YEAR));
}
上面的API虽然多,但是其实用的多的也就是获取年月日这些信息的API
代码执行结果(六)LocalDate
、LocalTime
、LocalDateTime
三者的转换
1、LocalDateTime转LocalDate和LocalTime
@Test
public void LocalDateTest(){
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
System.out.println("当前日期为:" + localDate);
System.out.println("当前时间为:" + localTime);
}
image.png
2、LocalDate转LocalDateTime
我们在只有日期对象的前提下,是需要指定好确切的时间才可以转化为LocalDateTime对象,毕竟程序不可能凭空给我们生成一个时间对象。下面介绍几个常用的API
名称 | 作用 |
---|---|
atStartOfDay | 获取当天最早的LocalDateTime对象 |
atTime(int hour, int minute) | 获取指定时间的LocalDateTime对象 |
atTime(int hour, int minute, int second) | 获取指定时间的LocalDateTime对象 |
atTime(OffsetTime time) | 获取指定时间的LocalDateTime对象 |
atTime(LocalTime time) | 获取指定时间的LocalDateTime对象 |
我们可以看到,LocalDate中提供了相当丰富的转化方法来给我们去进行时间对象的转换
@Test
public void LocalDateTest(){
LocalDate localDate = LocalDate.now();
LocalDateTime localDateTime1 = localDate.atStartOfDay();
LocalDateTime localDateTime2 = localDate.atTime(8,30);
LocalDateTime localDateTime3 = localDate.atTime(OffsetTime.MAX).toLocalDateTime();
LocalDateTime localDateTime4 = localDate.atTime(LocalTime.now());
System.out.println("localDateTime1时间为:" + localDateTime1);
System.out.println("localDateTime2时间为:" + localDateTime2);
System.out.println("localDateTime3时间为:" + localDateTime3);
System.out.println("localDateTime4时间为:" + localDateTime4);
}
代码执行结果
LocalDate可以转LocalDateTime对象的话,那么后续再转成LocalTime对象也就十分简单了,所以LocalDate转LocalTime这部分就不额外展开了。
(七)其他API
名称 | 作用 |
---|---|
range | 获取给出指定字段的有效值范围 |
isLeapYear | 检查当年是否为闰年 |
adjustInto | 将指定的时间对象调整为与此对象具有相同的日期 |
isSupported | 检查是否支持给定的单位。在使用加减之前,我们可以检查是否支持给定的单位,否则我们可能会出错。 |
until | 计算两个日期之间的时间量 |
@Test
public void LocalDateTest(){
LocalDate localDate = LocalDate.now();
// range 的使用
System.out.println("月份的范围为:" + localDate.range(ChronoField.MONTH_OF_YEAR));
// isLeapYear 是否为闰年
System.out.println("是否为闰年:" + localDate.isLeapYear());
// adjustInto 把对象的日期复制给传入的时间对象
Temporal resultDate = localDate.adjustInto(LocalDate.parse("2018-01-01"));
System.out.println("复制后的结果如下:" + resultDate);
// until
System.out.println("间隔的月份数为:" + localDate.until(LocalDate.parse("2022-06-01")).getMonths());
// isSupported
System.out.println("对象是否支持年份计算" + localDate.isSupported(ChronoField.YEAR));
System.out.println("对象是否支持小时计算" + localDate.isSupported(ChronoField.HOUR_OF_DAY));
}
代码执行结果
三、java.util.Date类和LocalDate的区别
1、java.util.Date
类能表示的最早日期为1970-01-01,而LocalDate
能表示的年份为-999999999 - 999999999
,可以说从时间范围上来看,后者是远比前者要大的。
2、LocalDate的API要更加的丰富和完善,且日期格式化也不需要专门创建一个日期格式化对象来处理
3、LocalDate对象是线程安全的,而java.util.Date
类则是线程不安全的。具体可以看下面这篇文章:
实际上,LocalDate作为后来者在不少地方都实现了比Date类更加完善的功能
PS:当遇到需要java.util.Date
转LocalDate
类型的场景时,我们可以怎么实现呢?个人觉得可以定义一个统一的日期格式,借助字符串作为桥梁来转换。
@Test
public void UtilsDateTest(){
Date date = new Date(0,10,10);
String strDate = new SimpleDateFormat("yyyy - MM - dd").format(date);
System.out.println("转换后的字符串日期为:" + strDate);
LocalDate localDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy - MM - dd"));
System.out.println("转换后的LocalDate对象为:" + localDate);
}
总结
至此,本篇文章对于LocalDate的介绍就到此介绍。LocalDate系列的日期时间类工具都有着十分实用的功能,适当了解相信可以在一定程度上为大家简化一下代码的开发。
参考文章:
【Java 8 新特性】Java LocalDate 详解
https://blog.csdn.net/qq_42295268/article/details/112503983
JDK官方文档:
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
https://www.concretepage.com/java/java-8/java-localdate
网友评论