! 版权声明: 本博客内容均均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。
目录[-]
如果对你有帮助,别忘了 Github 点颗星嘞~
从 Java 1.0 开始,就提供了对日期与时间处理的 ava.util.Date 类,它允许把日期解释为年、月、日、小时、分钟和秒值,也允许格式化和解析日期字符串。不过,这些函数的 API 不易于实现国际化。在升级版本到 Java 1.1 前,Java 维护者认为 Date 类很难被重新构造,由于这个原因,Java 1.1 增加了一个新的 java.util.Calendar 类。Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和解析日期字符串。可是在开发者使用过程中感受到,Calendar 类并不比 Date 类好用,它们面临的部分问题是:
自 2001 年起 Joda-Time 项目发布,它提供了简单易用且线程安全的时间类库,很快在 Java 社区中流行并广泛使用。Java 维护人员考虑到 JDK 中也需要一个这样的库,于是就与 巴西的 Michael Nascimento Santos 合作,Java 官方 JDK 新增了的时间/日期 API的进程(JSR-310)。
新增的时间 API 由 5 个包组成,如下:
一些基础概念有助于我们更加理解时间类,所以我们需要了解一下。
每个地区都有自己的本地时间,在网上以及无线电通信中时间转换的问题就显得格外突出。整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,都与英国伦敦的本地时相同:
例如,北京时区是东八区,领先 UTC 八个小时,在电子邮件信头的 Date 域记为+0800,如果在电子邮件的信头中有这么一行 Date:Fri, 08 Nov 2020 10:30:00 +0800 说明信件的发送地的地方时间是 2020 年 11 月 8 号,星期五,早上 10:30:00,这个地方的本地时领先 UTC 8 个小时(+0800,就是东八区时间) 。电子邮件信头的 Date 域使用二十四小时的时钟,而不使用 AM 和 PM 来标记上下午。
以上面电子邮件的发送时间为例,如果要把这个时间转化为UTC,可以使用一下公式:
UTC + 时区差 = 本地时间
时区差东为正,西为负。在此,把东八区时区差记为 +0800,
UTC + 0800 = 北京时间(本地时间)
那么 UTC 时间为:
北京时间(本地时间) - 0800 = UTC
简单的说 UTC 和 GMT 基本相等,但是 UTC 比 GMT 时间更为精准 ,他们区别如下:
输出类型 | 描述 |
---|---|
2019-06-10T03:48:20.847Z | 世界标准时间,T:日期和时间分隔,Z:世界标准时间 |
2019-06-10T11:51:48.872 | 不含时区信息的时间 |
2019-06-10T11:55:04.421+08:00[Asia/Shanghai] | 包含时区信息的时间,+08:00 表示相对于0时区加 8 小时,[Asia/Shanghai]:时区 |
JDK 8 新时间 API 中增加了很多处理时间的类,主要有如下:
新的时间 API 提供了很多时间操作类和方法,不过常用的是 LocalDate 和 LocalDateTime,下面是各个类的方法使用示例,可以简单看看,在实际中如果是需要可以参考使用:
表示时刻,时间线上的一个瞬时点,常用于获取纪元时的秒、毫秒等时间戳。
import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; public class InstantExample { /** * 获取时刻并进行转换 */ public static void instantTransition() { /* 获取时刻 */ // 获取当前时刻 Instant instant = Instant.now(); // 获取当前时刻的纳秒 long microsecond = instant.getNano(); // 获取当前时刻按纪元时转换后的毫秒(从1970-01-01T00:00:00Z.起) long millisecond = instant.toEpochMilli(); // 获取当前时刻按纪元时转换后的秒(从1970-01-01T00:00:00Z.起) long second = instant.getEpochSecond(); /* 输出 */ System.out.println("获取当前时刻:" + instant); System.out.println("获取当前时间的纳秒:" + microsecond); System.out.println("获取当前时刻按纪元时转换后的毫秒:" + millisecond); System.out.println("获取当前时刻按纪元时转换后的秒:" + second); System.out.println("-------------------------------------------------"); } /** * 时刻比较 */ public static void instantCompare() { /* 根据毫秒创建两个时刻 */ Instant instant1 = Instant.ofEpochMilli(1591113400000L); Instant instant2 = Instant.ofEpochMilli(1591113410000L); /* 两个时刻间比较 */ // 比较两个 Instant 时刻,如果返回是正数则大于,否则相反 int difference = instant1.compareTo(instant2); // 比较 instant1 是否在 instant2 时刻之后 boolean isAfter = instant1.isAfter(instant2); // 比较 instant1 是否在 instant2 时刻之前 boolean isBefore = instant1.isBefore(instant2); /* 输出 */ System.out.println("比较 instant1 是否在 instant2 时刻之后:" + isAfter); System.out.println("比较 instant1 是否在 instant2 时刻之前:" + isBefore); System.out.println("比较 Instant 对象的差值:" + difference); System.out.println("-------------------------------------------------"); } /** * 时刻计算 */ public static void instantCalculation() { /* 获取当前时刻 */ Instant instant = Instant.now(); /* 时刻计算 */ // 计算3天前的时间 Instant instantPlus = instant.plus(3, ChronoUnit.DAYS); // 计算6天前的时间 Instant instantMinus = instant.minus(6, ChronoUnit.DAYS); System.out.println("计算3天后的时刻:" + instantPlus); System.out.println("计算6天前的时刻:" + instantMinus); /* 根据毫秒创建两个时刻 */ Instant instant1 = Instant.ofEpochMilli(1591113400000L); Instant instant2 = Instant.ofEpochMilli(1591113410000L); // 计算两个 Instant 之间的秒数(如果返回负数则大于,返回负数则小于) long diffAsMinutes = ChronoUnit.SECONDS.between(instant1, instant2); /* 输出 */ System.out.println("计算两个 Instant 之间的分钟数:" + diffAsMinutes); System.out.println("-------------------------------------------------"); } /** * Instant 用于时刻转换的静态方法 */ public static void instantStaticMethod() { /* 时刻的静态转换方法 */ // 通过纪元时(秒)获取时刻(从1970-01-01T00:00:00Z.起) Instant epochSecond = Instant.ofEpochSecond(1591113458L); // 通过纪元时(秒)获取时刻并设置纳秒(从1970-01-01T00:00:00Z.起) Instant epochSecondNano = Instant.ofEpochSecond(1591113458L, 100); // 通过纪元时(毫秒)获取时刻(从1970-01-01T00:00:00Z.起) Instant epochMilli = Instant.ofEpochMilli(1591113458000L); // 通过纪元时(毫秒)将 Date 转换为 Instant 对象 Date date = new Date(); Instant dateInstant = Instant.ofEpochMilli(date.getTime()); // 通过纪元时(毫秒)将 Instant 转换为 Date 对象 Date instantDate = new Date(Instant.now().toEpochMilli()); /* 输出 */ System.out.println("通过纪元时(秒)获取时刻:" + epochSecond); System.out.println("通过纪元时(秒)获取时刻并设置纳秒:" + epochSecondNano); System.out.println("通过纪元时(毫秒)获取时刻" + epochMilli); System.out.println("Date 转换 Instant 对象:" + dateInstant); System.out.println("Instant 转换 Date 对象:" + instantDate); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { // 获取时刻并进行转换 instantTransition(); // 时刻比较 instantCompare(); // 时刻计算 instantCalculation(); // Instant 用于时刻转换的静态方法 instantStaticMethod(); } }
输出如下:
## 获取时刻并进行转换 ------------------------------------------------- 获取当前时刻:2020-07-06T15:00:07.860Z 获取当前时间的纳秒:860000000 获取当前时刻按纪元时转换后的毫秒:1594047607860 获取当前时刻按纪元时转换后的秒:1594047607 ------------------------------------------------- ## 时刻比较 ------------------------------------------------- 比较 instant1 是否在 instant2 时刻之后:false 比较 instant1 是否在 instant2 时刻之前:true 比较 Instant 对象的差值:-1 ------------------------------------------------- ## 时刻计算 ------------------------------------------------- 计算3天后的时刻:2020-07-09T15:00:07.917Z 计算6天前的时刻:2020-06-30T15:00:07.917Z 计算两个 Instant 之间的分钟数:10 ------------------------------------------------- ## Instant 用于时刻转换的静态方法 ------------------------------------------------- 通过纪元时(秒)获取时刻:2020-06-02T15:57:38Z 通过纪元时(秒)获取时刻并设置纳秒:2020-06-02T15:57:38.000000100Z 通过纪元时(毫秒)获取时刻2020-06-02T15:57:38Z Date 转换 Instant 对象:2020-07-06T15:00:07.918Z Instant 转换 Date 对象:Mon Jul 06 23:00:07 CST 2020 -------------------------------------------------
表示时钟,此类常用于查找当前时刻。
import java.time.Clock; import java.time.Instant; import java.time.ZoneId; public class ClockExample { /** * 获取时钟 */ public static void getClock(){ /* 获取时钟 */ // 获取"系统时间"的时钟,并使用"UTC时区"对日期和时间进行转换 Clock utcClock = Clock.systemUTC(); // 获取"系统时间"的时钟,并使用"系统时区"对日期和时间进行转换 Clock systemZoneClock = Clock.systemDefaultZone(); // 获取"系统时间"的时钟,并使用"指定时区"对日期和时间进行转换 Clock zoneClock = Clock.system(ZoneId.of("Asia/Shanghai")); // 获取"固定时刻"的时钟,并"指定时区"对日期和时间进行转换 Clock fixedClock = Clock.fixed(Instant.now(), ZoneId.of("Asia/Shanghai")); /* 输出 */ System.out.println("获取/"系统时间/"的时钟,并使用/"UTC时区/"对日期和时间进行转换:" + utcClock); System.out.println("获取/"系统时间/"的时钟,并使用/"系统时区/"对日期和时间进行转换:" + systemZoneClock); System.out.println("获取/"系统时间/"的时钟,并使用/"指定时区/"对日期和时间进行转换:" + zoneClock); System.out.println("获取/"固定时刻/"的时钟,并/"指定时区/"对日期和时间进行转换:" + fixedClock); System.out.println("-------------------------------------------------"); } /** * 时钟实例中的方法 */ public static void clockMethod() { /* 获取系统时钟 */ Clock clock = Clock.systemDefaultZone(); /* 时钟常用方法 */ // 获取当前时钟的时刻 Instant instant = clock.instant(); // 获取当前时钟的当前毫秒时刻 long millis = clock.millis(); // 获取当前时钟的时区 ZoneId zoneId = clock.getZone(); // 获取当前时钟并指定时区 Clock zoneClock = clock.withZone(ZoneId.of("Asia/Shanghai")); /* 输出 */ System.out.println("获取当前时间的时钟,并使用UTC时区对日期和时间进行转换:" + clock); System.out.println("获取时钟的当前时刻:" + instant); System.out.println("获取时钟的当前毫秒瞬间:" + millis); System.out.println("获取用于创建日期和时间的时区:" + zoneId); System.out.println("返回带有不同时区的此时钟的副本:" + zoneClock); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { // 获取时钟实例 getClock(); // 时钟实例中的方法 clockMethod(); } }
输出如下:
## 获取时钟 -------------------------------------------------------------------------------------------------- 获取"系统时间"的时钟,并使用"UTC时区"对日期和时间进行转换:SystemClock[Z] 获取"系统时间"的时钟,并使用"系统时区"对日期和时间进行转换:SystemClock[Asia/Shanghai] 获取"系统时间"的时钟,并使用"指定时区"对日期和时间进行转换:SystemClock[Asia/Shanghai] 获取"固定时刻"的时钟,并"指定时区"对日期和时间进行转换:FixedClock[2020-07-06T14:56:56.362Z,Asia/Shanghai] -------------------------------------------------------------------------------------------------- ## 时钟实例中的方法 -------------------------------------------------------------------------------------------------- 获取当前时间的时钟,并使用UTC时区对日期和时间进行转换:SystemClock[Asia/Shanghai] 获取时钟的当前时刻:2020-07-06T14:56:56.372Z 获取时钟的当前毫秒瞬间:1594047416372 获取用于创建日期和时间的时区:Asia/Shanghai 返回带有不同时区的此时钟的副本:SystemClock[Asia/Shanghai] --------------------------------------------------------------------------------------------------
表示时间段,此类以秒和纳秒为单位对时间量进行建模,也用于处理两个日期
import java.time.Duration; import java.time.LocalDateTime; public class DurationExample { /** * 计算时间段 */ public static void dateDuration(){ /* 创建两个时间对象 */ LocalDateTime time1 = LocalDateTime.of(2018, 6,18,10,20,30); LocalDateTime time2 = LocalDateTime.of(2020, 8,22,12,20,30); // 创建时间段对象 Duration duration = Duration.between(time1, time2); /* 输出 */ System.out.println("小时时间段:" + duration.toHours()); System.out.println("分钟时间段:" + duration.toMinutes()); System.out.println("秒时间段:" + duration.getSeconds()); System.out.println("毫秒时间段:" + duration.toMillis()); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { // 计算时间段 dateDuration(); } }
输出如下:
## 计算时间段 ------------------------------------------------- 小时时间段:19106 分钟时间段:1146360 秒时间段:68781600 毫秒时间段:68781600000 -------------------------------------------------
表示日期,通常由”年”、”月”、”日”组成,该类封装了很多操作日期的方法;
import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class LocalDateExample { /** * 日期转换 */ public static void localDateTransition() { /* 在默认时区中从系统时钟获取当前日期 */ LocalDate localDate = LocalDate.now(); /* 日期转换 */ // 使用指定的格式化程序格式化此日期 String formatLocalDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")); // 指定年、月、日参数获取日期实例 LocalDate ymdLocalDate = LocalDate.of(2020, 6, 18); // 指定年和年中的天数参数获取日期实例 LocalDate ydLocalDate = LocalDate.ofYearDay(2020, 100); // 通过纪元时(天)获取日期实例(从1970-01-01起) LocalDate epochDayLocalDate = LocalDate.ofEpochDay(10); /* 输出 */ System.out.println("在默认时区中从系统时钟获取当前日期:" + localDate); System.out.println("使用指定的格式化程序格式化此日期:" + formatLocalDate); System.out.println("根据设置年、月、日参数获取日期实例:" + ymdLocalDate); System.out.println("指定年和年中的天数参数获取日期实例:" + ydLocalDate); System.out.println("通过纪元时(天)获取日期实例:" + epochDayLocalDate); System.out.println("-------------------------------------------------"); } /** * 日期比较 */ public static void localDateCompare() { /* 创建两个日期实例 */ LocalDate localDate1 = LocalDate.of(2020, 6, 18); LocalDate localDate2 = LocalDate.of(2020, 6, 17); /* LocalDate 日期比较 */ // 比较两个 LocalDate 日期,如果返回是正数则大于,否则相反 int difference = localDate1.compareTo(localDate2); // 检查此日期是否在指定的日期之后 boolean isAfter = localDate1.isAfter(localDate2); boolean isBefore = localDate1.isBefore(localDate2); /* 输出 */ System.out.println("比较 LocalDate 对象的差值:" + difference); System.out.println("检查此日期是否在指定的日期之后:" + isAfter); System.out.println("检查此日期是否在指定的日期之前:" + isBefore); System.out.println("-------------------------------------------------"); } /** * 日期计算 */ public static void localDateCalculation() { /* 在默认时区中从系统时钟获取当前日期 */ LocalDate localDate = LocalDate.now(); /* 日期计算 */ // 获取在当前日期基础(增加)指定(天数)的日期 LocalDate plusLocalDate = localDate.plusDays(10); // 获取在当前日期基础(减少)指定(天数)的日期 LocalDate minusLocalDate = localDate.minusDays(10); /* 输出 */ System.out.println("获取在当前日期基础(增加)指定(天数)的日期:" + plusLocalDate); System.out.println("获取在当前日期基础(减少)指定(天数)的日期:" + minusLocalDate); System.out.println("-------------------------------------------------"); } /** * 检查是否为闰年 */ public static void checkLeapYear() { LocalDate localDate = LocalDate.now(); boolean isLeapYear = localDate.isLeapYear(); System.out.println(isLeapYear ? "今年是闰年" : "今年不是闰年"); System.out.println("-----------------------------------"); } public static void main(String[] args) { // 日期转换 localDateTransition(); // 日期比较 localDateCompare(); // 日期计算 localDateCalculation(); // 检查是否为闰年 checkLeapYear(); } }
输出如下:
## 日期转换 ------------------------------------------------- 在默认时区中从系统时钟获取当前日期:2020-07-06 使用指定的格式化程序格式化此日期:2020/07/06 根据设置年、月、日参数获取日期实例:2020-06-18 指定年和年中的天数参数获取日期实例:2020-04-09 通过纪元时(天)获取日期实例:1970-01-11 ------------------------------------------------- ## 日期比较 ------------------------------------------------- 比较 LocalDate 对象的差值:1 检查此日期是否在指定的日期之后:true 检查此日期是否在指定的日期之前:false ------------------------------------------------- ## 日期计算 ------------------------------------------------- 获取在当前日期基础(增加)指定(天数)的日期:2020-07-16 获取在当前日期基础(减少)指定(天数)的日期:2020-06-26 ------------------------------------------------- ## 检查是否为闰年 ------------------------------------------------- 今年是闰年 -------------------------------------------------
表示时间,通常由”时”、”分”、”秒”组成,该类封装了很多操作时间的方法。
import java.time.LocalTime; import java.time.format.DateTimeFormatter; public class LocalTimeExample { /** * 时间转换 */ public static void localTimeTransition() { /* 在默认时区中从系统时钟获取当前时间 */ LocalTime localTime = LocalTime.now(); /* 时间转换 */ // 使用指定的格式化程序格式化此时间 String formatLocalTime = LocalTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")); // 指定时、分参数获取时间实例 LocalTime hmLocalTime = LocalTime.of(12, 30); // 指定时、分、秒参数获取时间实例 LocalTime hmsLocalTime = LocalTime.of(12, 30, 20); // 指定时、分、秒、纳秒参数获取时间实例 LocalTime hmsnLocalTime = LocalTime.of(12, 30, 20, 10000); // 指定秒参数获取时间实例 LocalTime secondOfDayLocalTime = LocalTime.ofSecondOfDay(3600); /* 输出 */ System.out.println("在默认时区中从系统时钟获取当前时间:" + localTime); System.out.println("使用指定的格式化程序格式化此时间:" + formatLocalTime); System.out.println("指定时、分参数获取时间实例:" + hmLocalTime); System.out.println("指定时、分、秒参数获取时间实例:" + hmsLocalTime); System.out.println("指定时、分、秒、纳秒参数获取时间实例:" + hmsnLocalTime); System.out.println("指定秒参数获取时间实例:" + secondOfDayLocalTime); System.out.println("-------------------------------------------------"); } /** * 时间比较 */ public static void localTimeCompare() { /* 创建两个时间实例 */ LocalTime localTime1 = LocalTime.of(12, 30); LocalTime localTime2 = LocalTime.of(12, 25); /* 时间比较 */ // 比较两个 LocalTime 时间,如果返回是正数则大于,否则相反 int difference = localTime1.compareTo(localTime2); // 检查此时间是否在指定的时间之后 boolean isAfter = localTime1.isAfter(localTime2); boolean isBefore = localTime1.isBefore(localTime2); /* 输出 */ System.out.println("比较 LocalTime 对象的差值:" + difference); System.out.println("检查此时间是否在指定的时间之后:" + isAfter); System.out.println("检查此时间是否在指定的时间之前:" + isBefore); System.out.println("-------------------------------------------------"); } /** * 时间计算 */ public static void localTimeCalculation() { /* 在默认时区中从系统时钟获取当前时间 */ LocalTime localTime = LocalTime.now(); /* 时间计算 */ // 获取在当前时间基础(增加)指定(秒)的时间 LocalTime plusSecondsLocalTime = localTime.plusSeconds(10); // 获取在当前时间基础(增加)指定(分钟)的时间 LocalTime plusMinutesLocalTime = localTime.plusMinutes(10); // 获取在当前时间基础(增加)指定(小时)的时间 LocalTime plusHoursLocalTime = localTime.plusHours(10); // 获取在当前时间基础(减少)指定(秒)的时间 LocalTime minusSecondsLocalTime = localTime.minusSeconds(10); // 获取在当前时间基础(减少)指定(分钟)的时间 LocalTime minusMinutesLocalTime = localTime.minusMinutes(10); // 获取在当前时间基础(减少)指定(小时)的时间 LocalTime minusHoursLocalTime = localTime.minusHours(10); /* 输出 */ System.out.println("获取在当前时间基础(增加)指定(秒)的时间:" + plusSecondsLocalTime); System.out.println("获取在当前时间基础(增加)指定(分钟)的时间:" + plusMinutesLocalTime); System.out.println("获取在当前时间基础(增加)指定(小时)的时间:" + plusHoursLocalTime); System.out.println("获取在当前时间基础(减少)指定(秒)的时间:" + minusSecondsLocalTime); System.out.println("获取在当前时间基础(减少)指定(分钟)的时间:" + minusMinutesLocalTime); System.out.println("获取在当前时间基础(减少)指定(小时)的时间:" + minusHoursLocalTime); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { /* 时间转换 */ localTimeTransition(); /* 时间比较 */ localTimeCompare(); /* 时间计算 */ localTimeCalculation(); } }
输出如下:
## 时间转换 -------------------------------------------------------- 在默认时区中从系统时钟获取当前时间:23:14:11.746 使用指定的格式化程序格式化此时间:11:14:11 指定时、分参数获取时间实例:12:30 指定时、分、秒参数获取时间实例:12:30:20 指定时、分、秒、纳秒参数获取时间实例:12:30:20.000010 指定秒参数获取时间实例:01:00 -------------------------------------------------------- ## 时间比较 -------------------------------------------------------- 比较 LocalTime 对象的差值:1 检查此时间是否在指定的时间之后:true 检查此时间是否在指定的时间之前:false -------------------------------------------------------- ## 时间计算 -------------------------------------------------------- 获取在当前时间基础(增加)指定(秒)的时间:23:14:21.759 获取在当前时间基础(增加)指定(分钟)的时间:23:24:11.759 获取在当前时间基础(增加)指定(小时)的时间:09:14:11.759 获取在当前时间基础(减少)指定(秒)的时间:23:14:01.759 获取在当前时间基础(减少)指定(分钟)的时间:23:04:11.759 获取在当前时间基础(减少)指定(小时)的时间:13:14:11.759 --------------------------------------------------------
表示日期时间,只不过该类不记录时区信息,是”时间”与”日期”的组合,该类封装了很多操作时间日期的方法。
import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.ValueRange; import java.util.Date; public class LocalDateTimeExample { /** * 时间转换 */ public static void localDateTimeTransition() { /* 在默认时区中从系统时钟获取当前时间日期 */ LocalDateTime localDateTime = LocalDateTime.now(); /* 在指定时区中从系统时钟获取当前时间日期*/ LocalDateTime localDateTimeZone = LocalDateTime.now(ZoneId.of("+08:00")); /* 时间转换 */ // 获取该日期时间是属于该(年)的第几天 int dayOfYear = localDateTime.getDayOfYear(); // 获取该日期时间是属于该(月)的第几天 int dayOfMonth = localDateTime.getDayOfMonth(); // 获取该日期时间是属于该(周)的第几天 DayOfWeek dayOfWeek = localDateTime.getDayOfWeek(); // 从时间日期中获取(年)信息 int year = localDateTime.getYear(); // 从时间日期中获取(月)信息 Month month = localDateTime.getMonth(); // 从时间日期中获取(小时)信息 int hour = localDateTime.getHour(); // 从时间日期中获取(分钟)信息 int minute = localDateTime.getMinute(); // 从时间日期中获取(秒)信息 int second = localDateTime.getSecond(); // 从时间日期中获取(纳秒)信息 int nano = localDateTime.getNano(); // 使用指定的格式化程序格式化时间日期 String formatLocalDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")); // 指定年、月、日、时、分参数获取日期时间实例 LocalDateTime ymdhmLocalDateTime = LocalDateTime.of(2020,6,18,12, 30); // 指定年、月、日、时、分、秒参数获取日期时间实例 LocalDateTime ymdhmsLocalDateTime = LocalDateTime.of(2020,6,18,12,30,20); // 指定使用纪元时(秒)参数获取时间实例 LocalDateTime epochSecondLocalDateTime = LocalDateTime.ofEpochSecond(30*366*24*60*60,0, ZoneOffset.UTC); /* 输出 */ System.out.println("在默认时区中从系统时钟获取当前时间日期:" + localDateTime); System.out.println("在指定时区中从系统时钟获取当前时间日期:" + localDateTimeZone); System.out.println("获取该日期时间是属于该(年)的第几天:" + dayOfYear); System.out.println("获取该日期时间是属于该(月)的第几天:" + dayOfMonth); System.out.println("获取该日期时间是属于该(周)信息,名:" + dayOfWeek.name() + "天值" + dayOfWeek.getValue() ); System.out.println("从时间日期中获取(年)信息:" + year); System.out.println("从时间日期中获取(月份)信息,名:" + month.name() + "月份值" + month.getValue()); System.out.println("从时间日期中获取(小时)信息:" + hour); System.out.println("从时间日期中获取(分钟)信息:" + minute); System.out.println("从时间日期中获取(秒)信息:" + second); System.out.println("从时间日期中获取(纳秒)信息:" + nano); System.out.println("在默认时区中从系统时钟获取当前日期时间:" + localDateTime); System.out.println("使用指定的格式化程序格式化日期时间:" + formatLocalDateTime); System.out.println("指定年、月、日、时、分参数获取日期时间实例:" + ymdhmLocalDateTime); System.out.println("指定年、月、日、时、分、秒参数获取日期时间实例:" + ymdhmsLocalDateTime); System.out.println("指定使用纪元时(秒)参数获取时间实例:" + epochSecondLocalDateTime); System.out.println("-------------------------------------------------"); } /** * 日期时间比较 */ public static void localDateTimeCompare() { /* 创建两个日期时间实例 */ LocalDateTime localDateTime1 = LocalDateTime.of(2020,6,18,11, 30); LocalDateTime localDateTime2 = LocalDateTime.of(2020,6,18,12, 30); /* 日期时间比较 */ // 比较两个 LocalDateTime 日期时间,如果返回是正数则大于,否则相反 int difference = localDateTime1.compareTo(localDateTime2); // 检查此日期时间是否在指定的日期之后 boolean isAfter = localDateTime1.isAfter(localDateTime2); boolean isBefore = localDateTime1.isBefore(localDateTime2); // 以指定单位计算直到另一个日期时间的时间量并指定时间单位 long until = localDateTime1.until(localDateTime2, ChronoUnit.SECONDS); /* 输出 */ System.out.println("比较 LocaDatelTime 对象的差值:" + difference); System.out.println("检查此日期时间是否在指定的时间之后:" + isAfter); System.out.println("检查此日期时间是否在指定的时间之前:" + isBefore); System.out.println("以指定单位计算直到另一个日期时间的时间量并指定时间单位:" + until); System.out.println("-------------------------------------------------"); } /** * 日期时间计算 */ public static void localDateTimeCalculation() { /* 获取日期时间对象 */ // 在默认时区中从系统时钟获取当前日期时间 LocalDateTime localDateTime = LocalDateTime.now(); // 获取在当前日期时间基础(增加)指定(秒)的日期时间 LocalDateTime plusSecondsLocalDateTime = localDateTime.plusSeconds(30); // 获取在当前日期时间基础(增加)指定(分钟)的日期时间 LocalDateTime plusMinutesLocalDateTime = localDateTime.plusMinutes(10); // 获取在当前日期时间基础(增加)指定(小时)的日期时间 LocalDateTime plusHoursLocalDateTime = localDateTime.plusHours(10); // 获取在当前日期时间基础(增加)指定(天)的日期时间 LocalDateTime plusDaysLocalDateTime = localDateTime.plusDays(10); // 获取在当前日期时间基础(增加)指定(周)的日期时间 LocalDateTime plusWeeksLocalTime = localDateTime.plusWeeks(1); // 获取在当前日期时间基础(增加)指定(年)的日期时间 LocalDateTime plusYearsLocalTime = localDateTime.plusYears(1); // 获取在当前日期时间基础(减少)指定(秒)的日期时间 LocalDateTime minusSecondsLocalDateTime = localDateTime.minusSeconds(30); // 获取在当前日期时间基础(减少)指定(分钟)的日期时间 LocalDateTime minusMinutesLocalTime = localDateTime.minusMinutes(30); // 获取在当前日期时间基础(减少)指定(小时)的日期时间 LocalDateTime minusHoursLocalTime = localDateTime.minusHours(10); // 获取在当前日期时间基础(减少)指定(天)的日期时间 LocalDateTime minusDaysLocalTime = localDateTime.minusDays(10); // 获取在当前日期时间基础(减少)指定(周)的日期时间 LocalDateTime minusWeeksLocalTime = localDateTime.minusWeeks(1); // 获取在当前日期时间基础(减少)指定(年)的日期时间 LocalDateTime minusYearsLocalTime = localDateTime.minusYears(1); /* 输出 */ System.out.println("获取在当前日期时间基础(增加)指定(秒)的日期时间:" + plusSecondsLocalDateTime); System.out.println("获取在当前日期时间基础(增加)指定(分钟)的日期时间:" + plusMinutesLocalDateTime); System.out.println("获取在当前日期时间基础(增加)指定(小时)的日期时间:" + plusHoursLocalDateTime); System.out.println("获取在当前日期时间基础(增加)指定(天)的日期时间:" + plusDaysLocalDateTime); System.out.println("获取在当前日期时间基础(增加)指定(周)的日期时间:" + plusWeeksLocalTime); System.out.println("获取在当前日期时间基础(增加)指定(年)的日期时间:" + plusYearsLocalTime); System.out.println("获取在当前日期时间基础(减少)指定(秒)的日期时间:" + minusSecondsLocalDateTime); System.out.println("获取在当前日期时间基础(减少)指定(分钟)的日期时间:" + minusMinutesLocalTime); System.out.println("获取在当前日期时间基础(减少)指定(小时)的日期时间:" + minusHoursLocalTime); System.out.println("获取在当前日期时间基础(减少)指定(天)的日期时间:" + minusDaysLocalTime); System.out.println("获取在当前日期时间基础(减少)指定(周)的日期时间:" + minusWeeksLocalTime); System.out.println("获取在当前日期时间基础(减少)指定(年)的日期时间:" + minusYearsLocalTime); System.out.println("-------------------------------------------------"); } /** * Instance 转换为 LocalDateTime 转换 */ public static void instantToLocalDateTime(){ /* 创建 Instant 对象 */ Instant instant = Instant.now(); /* Instant 和 LocalDateTime 对象互转 */ // 将 Instant 对象转换为 LocalDateTime 对象并设置时区 LocalDateTime zoneLocalDateTime = LocalDateTime.ofInstant(instant,ZoneId.of("UTC")); // 将 LocalDateTime 对象转换为 Instant Instant localDateTaimeToInstant = zoneLocalDateTime.toInstant(ZoneOffset.UTC); /* 输出 */ System.out.println("将 Instant 对象转换为 LocalDateTime 对象并设置时区:" + zoneLocalDateTime); System.out.println("将 LocalDateTime 对象转换为 Instant:" + localDateTaimeToInstant); System.out.println("-------------------------------------------------"); } /** * LocalTime 与 LocalDateTime 转换 */ public static void localTime(){ /* 获取本地日期时间对象 */ LocalDateTime localDateTime = LocalDateTime.now(); /* 获取指定字段的有效值范围 */ // 获取指定字段的有效值范围(天/年) ValueRange valueRangeDayOfYear = localDateTime.range(ChronoField.DAY_OF_YEAR); // 获取指定字段的有效值范围(天/星期) ValueRange valueRangeDayOfWeek = localDateTime.range(ChronoField.DAY_OF_WEEK); /* 输出 */ System.out.println("获取指定字段的有效值范围,今年天数最大值:" + valueRangeDayOfYear.getMaximum()); System.out.println("获取指定字段的有效值范围,今年天数最小值:" + valueRangeDayOfYear.getMinimum()); System.out.println("获取指定字段的有效值范围,这星期数最大值:" + valueRangeDayOfWeek.getMaximum()); System.out.println("获取指定字段的有效值范围,这星期数最小值:" + valueRangeDayOfWeek.getMinimum()); System.out.println("-------------------------------------------------"); } /** * LocalDateTime 与 Date 的相互转换 */ public static void localDateTimeAndDate(){ // Date 转换为 LocalDateTime Date date1 = new Date(); LocalDateTime localDateTime1 = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault()); // LocalDateTime 转换为 Date LocalDateTime localDateTime2 = LocalDateTime.now(); Date date2 = Date.from(localDateTime2.atZone(ZoneId.systemDefault()).toInstant()); /* 输出 */ System.out.println("Date 转换为 LocalDateTime:" + localDateTime1); System.out.println("LocalDateTime转换为Date :" + date2); } public static void main(String[] args) { // 日期时间转换 localDateTimeTransition(); // 日期时间比较 localDateTimeCompare(); // 日期时间计算 localDateTimeCalculation(); // instant 转换为 LocalDateTime 对象 instantToLocalDateTime(); // LocalTime 与 LocalDateTime 转换 localTime(); // LocalDateTime 与 Date 的相互转换 localDateTimeAndDate(); } }
输出如下:
## 时间转换 ----------------------------------------------------------------------------- 在默认时区中从系统时钟获取当前时间日期:2020-07-06T23:10:32.791 在指定时区中从系统时钟获取当前时间日期:2020-07-06T23:10:32.791 获取该日期时间是属于该(年)的第几天:188 获取该日期时间是属于该(月)的第几天:6 获取该日期时间是属于该(周)信息,名:MONDAY天值1 从时间日期中获取(年)信息:2020 从时间日期中获取(月份)信息,名:JULY月份值7 从时间日期中获取(小时)信息:23 从时间日期中获取(分钟)信息:10 从时间日期中获取(秒)信息:32 从时间日期中获取(纳秒)信息:791000000 在默认时区中从系统时钟获取当前日期时间:2020-07-06T23:10:32.791 使用指定的格式化程序格式化日期时间:2020-07-06 11:10:32 指定年、月、日、时、分参数获取日期时间实例:2020-06-18T12:30 指定年、月、日、时、分、秒参数获取日期时间实例:2020-06-18T12:30:20 指定使用纪元时(秒)参数获取时间实例:2000-01-24T00:00 ----------------------------------------------------------------------------- ## 日期时间比较 ----------------------------------------------------------------------------- 比较 LocaDatelTime 对象的差值:-1 检查此日期时间是否在指定的时间之后:false 检查此日期时间是否在指定的时间之前:true 以指定单位计算直到另一个日期时间的时间量并指定时间单位:3600 ----------------------------------------------------------------------------- ## 日期时间计算 ----------------------------------------------------------------------------- 获取在当前日期时间基础(增加)指定(秒)的日期时间:2020-07-06T23:11:02.805 获取在当前日期时间基础(增加)指定(分钟)的日期时间:2020-07-06T23:20:32.805 获取在当前日期时间基础(增加)指定(小时)的日期时间:2020-07-07T09:10:32.805 获取在当前日期时间基础(增加)指定(天)的日期时间:2020-07-16T23:10:32.805 获取在当前日期时间基础(增加)指定(周)的日期时间:2020-07-13T23:10:32.805 获取在当前日期时间基础(增加)指定(年)的日期时间:2021-07-06T23:10:32.805 获取在当前日期时间基础(减少)指定(秒)的日期时间:2020-07-06T23:10:02.805 获取在当前日期时间基础(减少)指定(分钟)的日期时间:2020-07-06T22:40:32.805 获取在当前日期时间基础(减少)指定(小时)的日期时间:2020-07-06T13:10:32.805 获取在当前日期时间基础(减少)指定(天)的日期时间:2020-06-26T23:10:32.805 获取在当前日期时间基础(减少)指定(周)的日期时间:2020-06-29T23:10:32.805 获取在当前日期时间基础(减少)指定(年)的日期时间:2019-07-06T23:10:32.805 ----------------------------------------------------------------------------- ## Instance 转换为 LocalDateTime 转换 ----------------------------------------------------------------------------- 将 Instant 对象转换为 LocalDateTime 对象并设置时区:2020-07-06T15:10:32.806 将 LocalDateTime 对象转换为 Instant:2020-07-06T15:10:32.806Z ----------------------------------------------------------------------------- ## LocalTime 与 LocalDateTime 转换 ----------------------------------------------------------------------------- 获取指定字段的有效值范围,今年天数最大值:366 获取指定字段的有效值范围,今年天数最小值:1 获取指定字段的有效值范围,这星期数最大值:7 获取指定字段的有效值范围,这星期数最小值:1 ----------------------------------------------------------------------------- ## LocalDateTime 与 Date 的相互转换 ----------------------------------------------------------------------------- Date 转换为 LocalDateTime:2020-07-06T23:10:32.806 LocalDateTime转换为Date :Mon Jul 06 23:10:32 CST 2020 -----------------------------------------------------------------------------
该类中的方法基本和 LocalDateTime 一致,不过该类会记录时区信息。
import java.time.*; public class ZonedDateTimeExample { /** * ZonedDateTime 转换 */ public static void zoneTimeTransition() { /* 在默认时区中从系统时钟获取当前日期时间 */ ZonedDateTime zonedDateTime = ZonedDateTime.now(); /* ZonedDateTime 常用方法 */ // 获取时区信息 ZoneId zoneId = zonedDateTime.getZone(); // 转换为 LocalDate 对象 LocalDate localDate = zonedDateTime.toLocalDate(); // 转换为 LocalDateTime 对象 LocalDateTime localDateTime = zonedDateTime.toLocalDateTime(); // 转换为 OffsetDateTime 对象 OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime(); // 转换为 Instant 对象 Instant instant = zonedDateTime.toInstant(); // 指定年、月、日、时、分、秒参数获取日期时间实例 ZonedDateTime zonedDateTimeZone = ZonedDateTime.of(LocalDateTime.now(),ZoneId.of("GMT+8")); // 指定年、月、日、时、分参数获取日期时间实例 ZonedDateTime ymdhmsnZonedDateTimeZone = ZonedDateTime.of(2020,6,18,12, 30,1,0,ZoneId.of("GMT+8")); /* 输出 */ System.out.println("在默认时区中从系统时钟获取当前日期时间:" + zonedDateTime); System.out.println("获取时区信息:" + zoneId); System.out.println("转换为 LocalDate 对象:" + localDate); System.out.println("转换为 LocalDateTime 对象:" + localDateTime); System.out.println("转换为 OffsetDateTime 对象:" + offsetDateTime); System.out.println("转换为 Instant 对象:" + instant); System.out.println("指定年、月、日、时、分、秒参数获取日期时间实例:" + zonedDateTimeZone); System.out.println("指定年、月、日、时、分、秒参数获取日期时间实例:" + ymdhmsnZonedDateTimeZone); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { // ZonedDateTime 转换 zoneTimeTransition(); } }
输出如下:
## ZonedDateTime 转换 ------------------------------------------------------------------------------------------ 在默认时区中从系统时钟获取当前日期时间:2020-07-06T23:10:02.173+08:00[Asia/Shanghai] 获取时区信息:Asia/Shanghai 转换为 LocalDate 对象:2020-07-06 转换为 LocalDateTime 对象:2020-07-06T23:10:02.173 转换为 OffsetDateTime 对象:2020-07-06T23:10:02.173+08:00 转换为 Instant 对象:2020-07-06T15:10:02.173Z 指定年、月、日、时、分、秒参数获取日期时间实例:2020-07-06T23:10:02.173+08:00[GMT+08:00] 指定年、月、日、时、分、秒参数获取日期时间实例:2020-06-18T12:30:01+08:00[GMT+08:00] ------------------------------------------------------------------------------------------
Period 主要用于获取时间度量值,可以获取两个日期的年、月、日的差值等。
import java.time.LocalDate; import java.time.Period; public class PeriodExample { /** * 计算日期的差量 */ public static void datePeriod() { /* 创建两个日期对象 */ LocalDate localDate1 = LocalDate.of(2018, 6, 16); LocalDate localDate2 = LocalDate.of(2020, 8, 18); /* 获取由两个日期之间的年数、月数和天数组成的期间 */ Period period = Period.between(localDate1, localDate2); /* 输出 */ System.out.println("年差量:" + period.getYears()); System.out.println("月差量:" + period.getMonths()); System.out.println("日差量:" + period.getDays()); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { // 计算日期的差量 datePeriod(); } }
输出如下:
## 计算日期的差量 ------------ 年差量:2 月差量:2 日差量:2 ------------
主要用于创建 ZoneDateTime 时,指定时区选项,这里只介绍下如何创建 ZoneId 对象。
import java.time.OffsetDateTime; import java.time.ZoneId; public class ZoneIdExample { /** * 获取 ZoneId */ public static void getZoneId() { /* 获取时区ID */ ZoneId zoneId = ZoneId.systemDefault(); // 从时区 ID 获取 ZoneId 的实例 ZoneId zoneIdOf = ZoneId.of("+08:00"); // 获取包含偏移量的 ZoneId 实例 ZoneId zoneIdOfOffset = ZoneId.ofOffset("GMT", OffsetDateTime.now().getOffset()); /* 输出 */ System.out.println("获取系统默认的时区:" + zoneId.getId()); System.out.println("获取此ID的时区规则以执行计算:" + zoneId.getRules()); System.out.println("从时区ID获取 ZoneId 的实例:" + zoneIdOf); System.out.println("从时区ID获取 ZoneId 的实例:" + zoneIdOfOffset); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { // 获取 ZoneId getZoneId(); } }
输出如下:
## 获取 ZoneId ---------------------------------------------------------------------- 获取系统默认的时区:Asia/Shanghai 获取此ID的时区规则以执行计算:ZoneRules[currentStandardOffset=+08:00] 从时区ID获取 ZoneId 的实例:+08:00 从时区ID获取 ZoneId 的实例:GMT+08:00 ----------------------------------------------------------------------
表示时区偏移量,是 ZoneId 的子类,相对于格林尼治时间(GMT)的时间偏差,只是只处理与格林尼治的时间差;
import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.zone.ZoneRules; public class ZoneOffsetExample { /** * 获取现在日期时间的时区偏移量 */ public static void getNowZoneOffset(){ /* 获取 ZoneOffset 实例 */ ZoneOffset zoneOffsetNow = OffsetDateTime.now().getOffset(); /* 获取此偏移量相关时区的规则 */ ZoneRules zoneRules = zoneOffsetNow.getRules(); /* 输出 */ System.out.println("获取当前日期时间的【ZoneOffset】对象:" + zoneOffsetNow); System.out.println("获取此偏移量相关时区的规则:" + zoneRules); System.out.println("-------------------------------------------------"); } /** * 创建时区偏移量 */ public static void createZoneOffset() { /* 创建时区偏移量 */ // 使用【偏移量ID】获取【ZoneOffset】对象(最大支持的范围是从±18:00) ZoneOffset zoneOffsetOf = ZoneOffset.of("+08:00"); // 使用以【秒】为【偏移量ID】获取【ZoneOffset】对象(最大支持的范围是从±64800) ZoneOffset zoneOffsetSeconds = ZoneOffset.ofTotalSeconds(28800); // 使用以【小时】为【偏移量ID】获取【ZoneOffset】对象(最大支持的范围是从±18) ZoneOffset zoneOffsetByHours = ZoneOffset.ofHours(8); // 使用以【小时和分钟】为【偏移量ID】获取【ZoneOffset】对象(小时最大支持的范围是从±18,分钟的范围为±59) ZoneOffset zoneOffsetByHoursMinites = ZoneOffset.ofHoursMinutes(8, 30); // 使用以【小时、分钟和秒】为【偏移量ID】获取【ZoneOffset】对象(小时最大支持的范围是从±18,分钟的范围为±59,秒的范围为±59) ZoneOffset zoneOffsetByHoursMinutesSeconds = ZoneOffset.ofHoursMinutesSeconds(8, 30, 10); /* 输出 */ System.out.println("使用【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetOf); System.out.println("使用以【秒】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetSeconds); System.out.println("使用以【小时】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetByHours); System.out.println("使用以【小时与分钟】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetByHoursMinites); System.out.println("使用以【小时、分钟和秒】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetByHoursMinutesSeconds); System.out.println("-------------------------------------------------"); } /** * 时区偏移量比较 */ public static void compareZoneOffset() { /* 创建两个 ZoneOffset 实例 */ ZoneOffset zoneOffsetOf1 = ZoneOffset.of("+08:00"); ZoneOffset zoneOffsetOf2 = ZoneOffset.of("+09:00"); /* 时区偏移量比较 */ // 将此偏移量与另一个偏移量按降序比较(返回相差秒数) int seconds = zoneOffsetOf1.compareTo(zoneOffsetOf2); /* 输出 */ System.out.println("将此偏移量与另一个偏移量按降序比较:" + seconds); System.out.println("-------------------------------------------------"); } public static void main(String[] args) { // 获取现在日期时间的时区偏移量 getNowZoneOffset(); // 创建时区偏移量 createZoneOffset(); // 时区偏移量比较 compareZoneOffset(); } }
输出如下:
## 获取现在日期时间的时区偏移量 ------------------------------------------------------------------------ 获取当前日期时间的【ZoneOffset】对象:+08:00 获取此偏移量相关时区的规则:ZoneRules[currentStandardOffset=+08:00] ------------------------------------------------------------------------ ## 创建时区偏移量 ------------------------------------------------------------------------ 使用【偏移量ID】获取【ZoneOffset】对象:+08:00 使用以【秒】为【偏移量ID】获取【ZoneOffset】对象:+08:00 使用以【小时】为【偏移量ID】获取【ZoneOffset】对象:+08:00 使用以【小时与分钟】为【偏移量ID】获取【ZoneOffset】对象:+08:30 使用以【小时、分钟和秒】为【偏移量ID】获取【ZoneOffset】对象:+08:30:10 ------------------------------------------------------------------------ ## 时区偏移量比较 ------------------------------------------------------------------------ 将此偏移量与另一个偏移量按降序比较:3600 ------------------------------------------------------------------------
如果对你有帮助,别忘了 Github 点颗星嘞~
—END—