JDK8之LocalDateTime讲解
1 LocalDateTime
1.1 简介
LocalDateTime
是 Java 8
中日期时间 API
提供的一个类,在日期和时间的表示上提供了更加丰富和灵活的支持。
LocalDateTime
类相比于早期的 Date
和 Calendar
类来说有以下几个优势:
丰富的日期时间类型支持
:LocalDateTime
类封装了LocalDate
和LocalTime
两个类,支持更加细化的日期时间操作,例如获取某一天的开始和结束时间、获取某个时间段内的所有日期等。线程安全性
:LocalDateTime
类是不可变对象,线程安全性较高,可以在多线程环境下安全使用。时区支持
:LocalDateTime
类在处理时区相关的操作时有着很好的支持,例如可以将一个LocalDateTime
对象转换成ZonedDateTime
对象,以支持更加复杂的时区计算。
LocalDateTime
类的实现原理是基于 Java
的时间 API
,其内部实现主要依赖于 Java
中的 long
类型和标准 Unix
时间戳来表示日期时间。具体来说,LocalDateTime
内部包含了一个 long
类型的字段,用于表示自 UTC
(协调世界时)1970 年 1 月 1 日 00:00:00
开始经过的毫秒数(即 Unix 时间戳),通过对这个时间戳的操作来实现 LocalDateTime
类的各种功能。
同时,在实现时区相关的操作时,LocalDateTime
类还依赖于 Java
中的时区类(例如 ZoneId
和 ZoneOffset
),通过将 LocalDateTime
转换为 ZonedDateTime
或 OffsetDateTime
对象来实现时区相关的计算
1.2 LocalDateTime 的创建
LocalDateTime
类通过提供许多静态方法来创建对象,这些方法包括:
1.2.1 of() 方法
of()
方法用于根据指定的年、月、日、时、分、秒和纳秒值创建一个 LocalDateTime
对象,其语法如下:
public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond)
其中,year、month、dayOfMonth、hour、minute、second 和 nanoOfSecond
分别表示年、月、日、时、分、秒和纳秒值。
例如,以下代码创建了一个 LocalDateTime 对象,表示 2019 年 10 月 30 日 14 点 30 分 0 秒:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
1.2.2 now() 方法
now()
方法用于获取当前系统时间的 LocalDateTime
对象,其语法如下:
public static LocalDateTime now()
例如,以下代码创建了一个 LocalDateTime
对象,表示当前系统时间:
LocalDateTime dateTime = LocalDateTime.now();
1.2.3 parse() 方法
parse()
方法用于将一个字符串解析成 LocalDateTime
对象,其语法如下:
public static LocalDateTime parse(CharSequence text)
public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter)
其中,text
表示要解析的字符串,formatter
表示日期时间格式化对象。如果不指定 formatter
,则默认使用 ISO_LOCAL_DATE_TIME
格式。
例如,以下代码创建了一个 LocalDateTime
对象,表示 2019 年 10 月 30 日 14 点 30 分 0 秒:
LocalDateTime dateTime = LocalDateTime.parse("2019-10-30T14:30:00");
1.2.4 from() 方法
from()
方法用于将一个 TemporalAccessor
对象转换成 LocalDateTime
对象,其语法如下:
public static LocalDateTime from(TemporalAccessor temporal)
例如,以下代码将一个 ZonedDateTime
对象转换成 LocalDateTime
对象:
ZonedDateTime zonedDate = ZonedDateTime.of(2019, 10, 30, 14, 30, 0, 0, ZoneId.systemDefault());
LocalDateTime localDateTime = LocalDateTime.from(zonedDate);
1.3 LocalDateTime 的转换
LocalDateTime
类提供了许多方便的转换方法,我们可以把 LocalDateTime
转换成其他类型,或者把其他类型转换成 LocalDateTime
。这些方法包括:
1.3.1 toLocalDate() 方法
toLocalDate()
方法用于把 LocalDateTime
对象转换成 LocalDate
对象,其语法如下:
public LocalDate toLocalDate()
例如,以下代码将一个 LocalDateTime 对象转换成 LocalDate 对象:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
LocalDate date = dateTime.toLocalDate();
1.3.2 toLocalTime() 方法
toLocalTime()
方法用于把 LocalDateTime
对象转换成 LocalTime
对象,其语法如下:
public LocalTime toLocalTime()
例如,以下代码将一个 LocalDateTime 对象转换成 LocalTime 对象:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
LocalTime time = dateTime.toLocalTime();
1.3.3 atOffset() 方法
atOffset()
方法用于把 LocalDateTime
对象转换成带偏移量的 OffsetDateTime
对象,其语法如下:
public OffsetDateTime atOffset(ZoneOffset offset)
其中,offset
表示要添加的时区偏移量。
例如,以下代码将一个 LocalDateTime
对象转换成带偏移量的 OffsetDateTime
对象:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
ZoneOffset offset = ZoneOffset.of("+08:00");
OffsetDateTime offsetDateTime = dateTime.atOffset(offset);
1.3.4 toEpochSecond() 方法
toEpochSecond()
方法用于把 LocalDateTime
对象转换成 Unix
时间戳,其语法如下:
public long toEpochSecond(ZoneOffset offset)
其中,offset 表示要添加的时区偏移量。
例如,以下代码把一个 LocalDateTime
对象转换成 Unix 时间戳:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
ZoneOffset offset = ZoneOffset.of("+08:00");
long epochSecond = dateTime.toEpochSecond(offset);
1.3.5 from() 方法
from()
方法用于将一个 TemporalAccessor
对象转换成 LocalDateTime
对象,其语法与前面讲解的相同,这里不再赘述。
1.4 LocalDateTime 的格式化与解析
日期时间的格式化与解析是 Java 8
中日期时间 API
中的重要功能。LocalDateTime
类通过内置的 DateTimeFormatter
类以及一些方法来实现格式化和解析。下面我们将详细介绍 LocalDateTime
类的格式化和解析方法。
1.4.1 format() 方法
format()
方法用于将 LocalDateTime
对象格式化成字符串,其语法如下:
public String format(DateTimeFormatter formatter)
其中,formatter
表示日期时间格式化对象。
例如,以下代码将一个 LocalDateTime
对象格式化成 yyyy-MM-dd HH:mm:ss
格式的字符串:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String strDate = dateTime.format(formatter);
1.4.2 parse() 方法
parse()
方法用于将一个字符串解析成 LocalDateTime
对象,其语法在前面已经介绍过,这里不再赘述。
例如,以下代码将一个字符串解析成 LocalDateTime
对象:
LocalDateTime dateTime = LocalDateTime.parse("2019-10-30T14:30:00");
1.4.3 DateTimeFormatter 类
DateTimeFormatter
类是 Java 8
中提供的日期时间格式化类,它提供了多种内置的格式化方式,同时也可以自定义日期时间格式。常用的几种内置格式化方式包括:
ofPattern()
方法:使用指定的模式字符串创建一个DateTimeFormatter
对象。
public static DateTimeFormatter ofPattern(String pattern)
例如,以下代码创建了一个 "yyyy-MM-dd HH:mm:ss" 格式的 DateTimeFormatter 对象:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
ISO_LOCAL_DATE_TIME
:表示格式为yyyy-MM-ddTHH:mm:ss
的日期时间。
public static final DateTimeFormatter ISO_LOCAL_DATE_TIME
例如,以下代码创建了一个yyyy-MM-ddTHH:mm:ss
格式的DateTimeFormatter
对象:
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
ISO_LOCAL_DATE
:表示格式为yyyy-MM-dd
的日期。
public static final DateTimeFormatter ISO_LOCAL_DATE
例如,以下代码创建了一个yyyy-MM-dd
格式的DateTimeFormatter
对象:
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;
1.5 LocalDateTime 的计算与比较
LocalDateTime
类还提供了一些方法来进行日期时间的计算和比较。这些方法包括:
1.5.1 plusXxx() 和 minusXxx() 方法
plusXxx()
和 minusXxx()
方法分别用于在当前 LocalDateTime
对象上加上
或减去
指定的日期时间量,其中 Xxx
表示日期时间单位,如:Years、Months、Days、Hours、Minutes、Seconds 和 Nanos
。
例如,以下代码将一个 LocalDateTime 对象加上 1 年并减去 1 月:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
dateTime = dateTime.plusYears(1).minusMonths(1);
1.5.2 withXxx() 方法
withXxx()
方法用于以指定的日期时间量来修改 LocalDateTime 对象的对应字段,其他字段不变,其中 Xxx
表示日期时间单位,如:Year、Month、DayOfMonth、Hour、Minute、Second 和 Nano
。
例如,以下代码将 LocalDateTime
对象的年份修改为 2020 年:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
dateTime = dateTime.withYear(2020);
1.5.3 isBefore() 和 isAfter() 方法
isBefore()
和 isAfter()
方法分别用于判断两个 LocalDateTime
对象的先后顺序。其中,isBefore()
方法用于判断当前 LocalDateTime
对象是否在参数对象之前,isAfter()
方法用于判断当前 LocalDateTime
对象是否在参数对象之后。
例如,以下代码判断两个 LocalDateTime
对象的先后顺序:
LocalDateTime dateTime1 = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
LocalDateTime dateTime2 = LocalDateTime.of(2020, 10, 30, 14, 30, 0, 0);
boolean before = dateTime1.isBefore(dateTime2); // true
boolean after = dateTime1.isAfter(dateTime2); // false
1.6 LocalDateTime 的其他操作
LocalDateTime
类还提供了一些其他操作,这些操作包括:
1.6.1 with() 方法
with()
方法用于以指定的 TemporalAdjuster
对象或者方法来修改 LocalDateTime
对象,例如,以下代码将 LocalDateTime
对象的日期调整为当前月份的第一天:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
dateTime = dateTime.with(TemporalAdjusters.firstDayOfMonth());
其中,TemporalAdjusters
是 Java 8
中提供的一个类,它提供了许多方便的日期时间调整器,如:firstDayOfMonth()、lastDayOfMonth()、next()、previous()
等。通过调用这些方法可以生成对应的 TemporalAdjuster
对象。
1.6.2 getXXX() 方法
getXXX()
方法用于获取 LocalDateTime
对象的指定字段值,其中 Xxx
表示日期时间单位,如:Year、Month、DayOfMonth、Hour、Minute、Second 和 Nano
。
例如,以下代码获取 LocalDateTime 对象的月份和分钟数:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
int month = dateTime.getMonthValue(); // 10
int minute = dateTime.getMinute(); // 30
1.6.3 getDayOfWeek() 和 getDayOfMonth() 方法
getDayOfWeek()
和 getDayOfMonth()
方法分别用于获取 LocalDateTime
对象所表示日期的星期几和哪一天。例如,以下代码获取 LocalDateTime
对象的星期几和哪一天:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
DayOfWeek dayOfWeek = dateTime.getDayOfWeek(); // WEDNESDAY
int dayOfMonth = dateTime.getDayOfMonth(); // 30
1.6.4 toInstant() 方法
toInstant()
方法用于获取 LocalDateTime
对象的 Instant
对象,其中 Instant
对象表示了从 1970 年 1 月 1 日 00:00:00 GMT 开始的毫秒数例如,以下代码获取 LocalDateTime
对象的 Instant 对象:
LocalDateTime dateTime = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
Instant instant = dateTime.toInstant();
1.6.5 compareTo() 方法
compareTo()
方法用于比较两个 LocalDateTime
对象的顺序大小,如果当前对象在参数对象之前,则返回负数,如果当前对象在参数对象之后,则返回正数,如果两个对象相等,则返回 0。
例如,以下代码比较两个 LocalDateTime 对象的顺序:
LocalDateTime dateTime1 = LocalDateTime.of(2019, 10, 30, 14, 30, 0, 0);
LocalDateTime dateTime2 = LocalDateTime.of(2020, 10, 30, 14, 30, 0, 0);
int result = dateTime1.compareTo(dateTime2); // -1