Java8日期处理【上】(超详细、JDK8)

关于旧日期如何转换成Java8日期时间对象:

 

java

代码解读

复制代码

public static void main(String[] args) { // 创建一个老日期对象 Date date = new Date(); // 将老日期通过Java8的toInstant()方法转为Instant对象。 Instant instant = date.toInstant(); // 成功转换成Java8新日期 LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai")); System.out.println(date); // Fri Jul 26 16:34:22 CST 2024 System.out.println(ldt); // 2024-07-26T16:34:22.832 // 从新日期对象中转换成老日期对象 Instant ins = ldt.toInstant(ZoneOffset.of("+08:00")); Date from = Date.from(ins); System.out.println(from); // Fri Jul 26 16:34:22 CST 2024 // 总结:还是新日期看起来舒服得劲;具体的Instant使用请看下文的java8日期介绍 }


为何强烈推荐使用𝐽𝑎𝑣𝑎8日期:为何强烈推荐使用Java8日期:

  Java 8 引入了全新的日期和时间 API,位于java.time包中。这个 API 提供了一组全面的类来处理日期、时间、时区、持续时间等,解决了旧版java.util.Datejava.util.Calendar存在的许多问题,比如旧版的线程安全性差、API设计不佳、易用性差等,导致日期和时间的处理变得困难和容易出错。为了解决这些问题,JDK 1.8 引入了全新的日期时间API。所以使用新的日期时间 API 旨在提供更好的日期时间处理解决方案,弥补了之前 API 的不足之处。

关于日常容易混淆的单位转换:关于日常容易混淆的单位转换:

 

txt

代码解读

复制代码

1s【秒】 = 1000ms【毫秒】 1ms【毫秒】 = 1000μs【微秒】 1μs【微秒】 = 1000ns【纳秒】 1ns【纳秒】 = 1000ps【皮秒】 所以转换如下:1秒 = 1000(毫秒) = 1000,000(微秒) = 1000,000,000(纳秒) = 1000,000,000,000(皮秒)

𝐽𝑎𝑣𝑎1.8日期时间的整体组合:Java1.8日期时间的整体组合:

  上面只列举了大概java.time包下的类,其实还有如:OffsetTime(时间偏差)、Year(年)、YearMonth(年月)、MonthDay(月日);关于这些大家看完文章就会悟出来,下面将不再阐述这四个类。

二:常见枚举和静态方法速查

(一):ChronoField枚举类

  ChronoField类是java.time包中的一个枚举类,它定义了各种日期和时间字段,用于获取和操作日期时间对象的不同部分。常见的字段包括年份、月份、日、小时、分钟、秒等。

点击查看详情:关于TemporalField里的ChronoField枚举值说明

 

(二):ChronoUnit枚举类

  ChronoUnit是Java日期时间API中的一个枚举类型,它定义了日期时间的不同单位。

点开查看详情:关于TemporalUnit里的ChronoUnit枚举值说明

 

(三):TemporalAdjuster函数式接口

  TemporalAdjuster是函数式接口,用于便捷调整日期时间对象,如调整LocalDate、LocalDateTime等的值。它允许我们执行特定的日期调整操作。我们可以通过静态类的TemporalAdjusters对象快速创建需要的参数对象;如可以快速获取如下时间:当月开始、当月结束、下月开始、本年开始、本年结束、下年开始、下周时间、上周时间等便捷功能。

点开查看详情:关于TemporalAdjuster的函数式接口使用

整理了一份Java面试题笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记【点击此处】即可免费获取

三:LocalDate日期对象

  Java 8 提供了一套全新的日期和时间API。在java.time包下有个LocalDate类,它是一个不可变的(线程安全)日期时间对象,表示日期,通常被视为年月日。也可以访问其它日期字段,如:日期和星期。但是该类不存储或表示时间或时区哟。所以它不能代表线上时间的即时信息,也没有附加信息,如偏移或时区。这就导致了它只能存一些固定日期,如生日等信息。
  需要了解的是LocalDate创建出的日期是ISO-8601日历系统;有着闰年和平年的规则,适用于日常生活的公历日历系统。对于现在的大多数应用,ISO-8601规则是完全合适的。

(一):方法列表

点开查看详情:LocalDate日期对象方法列表说明

 

(二):常用方法讲解

1:日期创建和分量获取1:日期创建和分量获取
  说明:在公历历法中,没有一个称为公元0年的年份。相反该历法直接跳过了0年这个概念,将年份划分为公元前(BCE) 和 公元后(CE) 两部分。在使用或者获取年份的时候为0时则代表公元前1年,若在使用或者获取年份的时候为-1年时则代表公元前2年(比如-4代表公元前5年),若在使用或者获取年份的时候为1年则代表公元后1年,但通常不说公元后1年,而大部分时刻都叫它公元1年或者1年。

点看查看详情代码:日期创建和分量获取

 

2:日期的检查判断系列功能2:日期的检查判断系列功能

点看查看详情代码:日期的检查判断系列功能

 

3:日期的修改、增加、减少、相差方法3:日期的修改、增加、减少、相差方法

点看查看详情代码:日期的修改、增加、减少、相差方法

 

4:日期的比较、范围获取、其它方法4:日期的比较、范围获取、其它方法

点看查看详情代码:日期的比较、范围获取、其它方法

 

5:日期的组合和生成对应对象5:日期的组合和生成对应对象

点开查看详情代码:日期的组合和生成对应对象

 

四:LocalTime时间对象

  Java 8 中,LocalTime是用来 表示时间 类的,它和LocalDate表示日期其实差不多,只不过一个表示日期的年月日,另一个表示时间的时分秒和纳秒;而且它们都属于不可变且线程安全的日期时间类;需要注意的它不存储或表示日期或时区,也它不能代表时间线上的即时信息,没有附加信息,如偏移或时区。只适合处理不带时区的时间信息。
  那么LocalTime这个类可以用来处理不带时区的时间信息,它适合用于日常应用中不涉及日期的时间处理场景,例如会议时间、计划任务时间等。通过LocalTime也可以方便地进行时间的创建、格式化、解析、比较和修改等操作。

(一):方法列表

点开查看详情:LocalTime时间对象方法列表说明

 

(二):常用方法讲解

1:时间创建和分量获取1:时间创建和分量获取

点看查看详情代码:时间创建和分量获取

 

2:时间的检查判断系列功能2:时间的检查判断系列功能

点看查看详情代码:时间的检查判断系列功能

 

3:时间的修改、增加、减少、相差方法3:时间的修改、增加、减少、相差方法

点看查看详情代码:时间的修改、增加、减少、相差方法

 

4:时间的比较、范围获取、其它方法4:时间的比较、范围获取、其它方法

点看查看详情代码:时间的比较、范围获取、其它方法

 

5:时间的组合和生成对应对象5:时间的组合和生成对应对象

点开查看详情代码:时间的组合和生成对应对象

 

五:LocalDateTime日期时间对象

  LocalDateTime 是 Java 8 引入的 表示日期时间类,位于java.time包下。它结合了日期(年、月、日)和时间(时、分、秒、纳秒)信息,并且是不可变的线程安全的日期时间对象类;它还没有时区信息,所以适用于不依赖于特定时区的时间处理,例如表示某个具体的日历时间点。
  这个日期时间类提供了简单而强大的日期时间操作功能,适用于大多数本地日期时间需求,特别是当不需要考虑时区的时候使用。通过合理使用它的方法,可以方便地处理和操作日期时间信息。

(一):方法列表

  由于前面说了 LocalDate 和 LocalTime 这两个类的铺垫;所以 LocalDateTime 类看起来不会太难懂;下面我针对一些不好理解的方法进行说明;其它方式只用来基本查阅。

 

java

代码解读

复制代码

'1:一些基本的静态属性:(关于日期时间可设置的最大值和最小值)' static LocalDateTime MAX 最大可设置日期:'+ 999999999-12-31T23:59:59.999999999' static LocalDateTime MIN 最小可设置日期:'-999999999-01-01T00:00:00' '2:关于日期时间的创建和生成' static LocalDateTime now() static LocalDateTime now(Clock clock) static LocalDateTime now(ZoneId zone) 上面这3个方法用来创建具体的日期时间,不同的是不带参数的会创建当地默认时区的日期时间; 注:关于带参数创建会在指定的now章节详解。 static LocalDateTime of(LocalDate date, LocalTime time) 通过日期类和时间类来组装成一个日期时间对象 static LocalDateTime of(int year,int month,int dayOfMonth,int hour,int minute) static LocalDateTime of(int year,int month,int dayOfMonth,int hour,int minute,int second) static LocalDateTime of(int year,int month,int dayOfMonth,int hour,int minute,int second, int nanoOfSecond) static LocalDateTime of(int year,Month month,int dayOfMonth,int hour,int minute) static LocalDateTime of(int year,Month month,int dayOfMonth,int hour,int minute,int second) static LocalDateTime of(int year,Month month,int dayOfMonth,int hour,int minute,int second, int nanoOfSecond) 通过不同的年、月、日、时、分、秒、纳秒来创建日期时间对象 static LocalDateTime ofEpochSecond(long epochSecond, int nanoOfSecond, ZoneOffset offset) 从1970-01-01 00:00:00(零时区)的时间开始的指定秒数来获得一个日期时间类。时区偏移后面篇章说明。 static LocalDateTime ofInstant(Instant instant, ZoneId zone) 从Instant和区域ID获取一个LocalDateTime的实例。这两个类后面篇章说明。 '3:关于日期时间的分量获取' getYear()、getMonthValue()、getDayOfMonth()、getHour()、 getMinute()、getSecond()、getNano()、getDayOfYear() 获取int类型的 年、月(1~12)、日、时、分、秒、纳秒、一年中的第几天。 int get(TemporalField field) 获取指定字段的数值;方法使用都一样,但返回值不一样。因为有的返回值大需要用到Long。 如通过传入 ChronoField.YEAR 可以获取年份的整数值或者长整数值。 Month getMonth() 获取月份字段,返回一个Month枚举类型。 DayOfWeek getDayOfWeek() 获取日期对应的星期几,返回一个枚举类型DayOfWeek表示星期几。 '4:日期检查' boolean isAfter(ChronoLocalDateTime<?> other) 检查当前日期时间是否在指定日期时间之前。true代表是,反之false。 boolean isBefore(ChronoLocalDateTime<?> other) 检查当前日期时间是否在指定日期时间之后。true代表是,反之false。 boolean isEqual(ChronoLocalDateTime<?> other) 检查当前日期时间是否等于指定日期时间,它可以比较不同类型历法的日期时间,只要最终日期时间一样即可。 boolean equals(Object obj) 检查当前日期时间是否等于另一个日期,它只能比较同类型的历法日期时间对象 boolean isSupported(TemporalUnit unit) boolean isSupported(TemporalField field) 检查指定的ChronoUnit枚举字段和ChronoField枚举字段是否被支持。 '5:日期时间的修改、增加、减少、相差' '注:修改一般以with开头、增加一般以plus开头、减少一般以minus开头、相差一般以until开头' '注:关于修改、增加、减少、相差则去参考LocalDate和LocalTime,他们的方法这里都有' '注:关于日期的相差只有 long until(Temporal endExclusive, TemporalUnit unit)方法' '6:关于日期时间的比较' int compareTo(ChronoLocalDateTime<?> other) 将此时间与另一个时间进行比较。最终会返回:负数、0、正数; 说明:0代表时间相同、正数代表当前时间比传入的时间大、负数代表当前时间比传入的时间小。 '7:获取当前时间时间的各种数值的取值范围' ValueRange range(TemporalField field) 获取当前时间的指定ChronoField枚举字段的有效值的范围。 '8:日期时间拆分' LocalDate toLocalDate()、LocalTime toLocalTime() 将日期拆分成 LocalDate 或者 LocalTime '9:日期时间截断' LocalDateTime truncatedTo(TemporalUnit unit) 用于将当前日期时间对象按照指定的粒度单位进行截断操作,并返回一个新的LocalDateTime对象。 比如:2024-07-04T17:33:13.914 按照小时粒度截断则为 2024-07-04T17:00 '10:日期时间字符串转换于日期时间格式化方法(具体参考日期时间格式化章节)' String format(DateTimeFormatter formatter) static LocalDateTime parse(CharSequence text) static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) '11:日期时间组成指定对象' ZonedDateTime atZone(ZoneId zone) OffsetDateTime atOffset(ZoneOffset offset) 将此日期时间和传入的时区ID(ZoneId)或时区偏移(ZoneOffset)组合成指定的对象。 具体的这两个对象下文会专门介绍。 '12:其它方法' static LocalDateTime from(TemporalAccessor temporal) 从时间对象获取一个LocalDateTime的实例。具体查看from()方法详讲。 Temporal adjustInto(Temporal temporal) 调整指定的时间对象与此对象具有相同的日期和时间。 <R> R query(TemporalQuery<R> query) 使用指定的查询查询此日期时间。具体查看query()方法详讲。

(二):常用方法使用

  大部分方法在LocalDate和LocalTime中已经讲过了,在LocalDateTime中基本上都可以使用。

 

java

代码解读

复制代码

public static void main(String[] args) { // 创建一个以年、月、日、时、分、秒、纳秒来构建一个日期 LocalDateTime dt1 = LocalDateTime.of(2024, 7, 5, 12, 30, 25, 6900); // 以1970-01-01 00:00:00(零时区)日期往后加指定的秒和纳秒来构建日期时间 LocalDateTime dt2 = LocalDateTime.ofEpochSecond(1720153825, 20, ZoneOffset.of("+08:00")); System.out.println("日期1:" + dt1); // 日期1:2024-07-05T12:30:25.000006900 System.out.println("日期2:" + dt2); // 日期2:2024-07-05T12:30:25.000000020 System.out.println(dt2.getYear()+"-"+dt2.getMonthValue()+"-"+dt2.getDayOfMonth());//2024-7-5 // 说明:关于如下ChronoField的枚举字段必须使用getLong()方法获取: System.out.println(dt1.getLong(ChronoField.NANO_OF_DAY)); // 45025000006900 System.out.println(dt1.getLong(ChronoField.MICRO_OF_DAY)); // 45025000006 System.out.println(dt2.getLong(ChronoField.EPOCH_DAY)); // 19909 System.out.println(dt2.getLong(ChronoField.PROLEPTIC_MONTH)); // 24294 // 日期时间加减 System.out.println(dt1.plusDays(5)); // 2024-07-10T12:30:25.000006900 System.out.println(dt1.minusDays(5)); // 2024-06-30T12:30:25.000006900 }

六:Period时间段(日期)

  Java 8 中提出了 Period 时间段的类,它位于java.time包中,用于 表示日期间隔。主要用于计算和处理两个日期之间的差异,例如几年、几个月、几天等这样的时间段。注意的是Period对象是不可变的,一旦创建就不能被修改。这意味着每次修改操作都会返回一个新的Period实例,从而确保线程安全性。
  总结:Period类适合用于计算和表达人类习惯的日期间隔,例如计算两个日期之间的差距,或者在日期上进行简单的加减操作。它通常用于处理不需要精确到时分秒的日期计算需求。

(一):方法列表

点开查看详情:Period时间段方法列表

 

(二):常用方法讲解

点开查看详情:Period时间段方法基本说明

 

(三):关于Period时间段总结

  1. 以构造of方法创建出的Period对象,年月日之间不会自动完成转换,即不会有“进位”和“退位”效果。
  2. 以构造方式创建出的Period对象,调用其toTotalMonths()不一定能够准确的计算出该对象所代表的时间段中包含的月数,因为计算过程中并没有考虑“日计数器”上的值。
  3. normalized()方法只能在年和月之间完成换算,并不能把天换算成月,即使天数已经超过了31。

  说明:造成以上三种情况的原因可以统一归结为:日与月之间没有确定的换算标准。

七:Duration时间段(时间)

  与Period时间段类不同的是,Duration类用于 表示时间间隔,通常用于处理时间的差异,例如秒、纳秒等单位。主要用于精确的时间计算,可以跨越日期的边界,适合于需要精确到时分秒的时间间隔。需要注意的是Duration对象也是不可变的,类似于Period,因此在进行任何修改操作时会返回一个新的Duration实例,从而确保线程安全性。
  总结:当我们需要精确计算时间间隔的场景时,例如测量两个时间点之间的精确时间差、在时间戳上进行精确地加减操作等。

(一):方法列表

点开查看详情:Duration时间段方法列表

 

(二):常用方法讲解

点开查看详情:Duration时间段方法基本说明

 

(三):关于Duration时间段总结

  Duration创建的时间段都是会进行自动的进位或退位的,因为时分秒是有着换算方式。

八:ZoneId时区

  在 Java 8 中引入了一个全新的 ZoneId时区抽象类 ,被作为新的日期时间API(java.time包)的一部分。ZoneId取代了旧的 java.util.TimeZone 类,并提供了一种统一的方式来处理和表示不同的时区,适用于处理日期时间信息中的时区转换和处理操作。
  我们可以使用 ZoneId.of()方法 根据时区标识符字符串创建 ZoneId 对象。时区标识符通常采用 "大洲/城市" 的形式,例如 "Asia/Shanghai"(亚洲/上海) 或 "Europe/Paris"(欧洲/巴黎)。

(一):ZoneRegion、ZoneOffset

  ZoneId时区类它其实是一个抽象类,被设计出来是为了表示两个概念,分别表示地区和时差;正好ZoneId有两个子类,分别是ZoneRegion(表示时区)和ZoneOffset(表示时差), 需要注意的是它这两个实现类都是不可变的和线程安全的。
  ZoneRegion:用于表示具体的地理区域时区,例如 "Europe/Paris"、"America/New_York" 等。这些时区标识符通常由一个大洲或国家/地区和城市名组成,可以准确地反映出特定地区的时区规则和历史变化。
  ZoneOffset:表示的是与UTC或格林威治标准时间(GMT)的固定偏移量。它以形如 "+08:00"、"-05:00" 的格式表示,分别代表相对于UTC的小时和分钟偏移量。ZoneOffset主要用于表示不考虑夏令时变化的固定偏移量时区,如 "UTC+1" 或 "GMT-5"。

区别和用途:区别和用途:
  ZoneRegion:适合用于表示具体的地理区域时区,它包含了更多的时区规则信息,例如何时进行夏令时调整、偏移量的变化等。它是处理全球化应用中时区转换和时间计算的首选。
  ZoneOffset:则用于表示相对于UTC的固定偏移量,它通常不包含夏令时规则。它适合于那些不需要考虑夏令时变化,只需简单地表示时间偏移的场景。

(二):什么是GMT和UTC

  GMT(Greenwich Mean Time) 和 UTC(Coordinated Universal Time) 都是标准时间的名称,用于表示全球标准时间的参考基准。它们之间有一些历史上的差异,但在现代使用中,它们通常被视为相同的概念,尽管有些微小的差异。
  GMT(格林威治标准时间): 它是以英国伦敦的格林威治天文台为基准的时间标准。它最初是由天文观测员用来描述地球自转周期和天体观测的时间基准。以基于太阳穿越格林威治子午线的时间来定义。这种方法在20世纪70年代后逐渐被原子钟和UTC取代,但GMT仍然被广泛使用作为时间的标准。GMT通常与英国伦敦所在的时区一致 (UTC+0),但在夏季会有夏令时的调整 (GMT+1)。
  UTC(协调世界时): 它是由国际原子时(TAI)通过原子钟测量获得的时间标准。它旨在提供一个更准确和稳定的时间基准,取代了天文学上的GMT。UTC与地球自转没有直接关系,而是通过原子钟的国际协调来保持稳定和同步。它是一个统一的时间标准,不会因为夏令时而变化,与GMT在大多数情况下是一致的,但有微小的差异。
区别和用途:区别和用途:
  ▢:历史背景:GMT是早期基于天文观测的时间标准,而UTC是现代基于原子钟的国际标准。
  ▢:精度:UTC比GMT更准确和稳定,因为它直接基于原子钟的测量。
  ▢:使用:在航空航天、国际通讯等领域,通常使用UTC作为时间标准,因为它更精确和普遍接受。
注:𝐽𝑎𝑣𝑎8新日期时间系统中,𝐺𝑀𝑇与𝑈𝑇𝐶并无数值上的差别。注:Java8新日期时间系统中,GMT与UTC并无数值上的差别。

(三):方法列表

  我们可以使用ZoneId来创建出ZoneRegion和ZoneOffset类型的时区,但 无法直接使用 ZoneRegion 类,因为它这个类访问修饰符为default,只能在当前包下使用,我们无法进行使用,但ZoneOffset却可以正常使用。

 

java

代码解读

复制代码

'================ 关于抽象ZoneId类说明;但最终由ZoneRegion、ZoneOffset实现 ================' '1:静态常量' static Map<String,String> SHORT_IDS 区域短名称,它内部存放了28个常用的区域映射。比如上海我们只需要设置CTT即可。 如:CTT=(Asia/Shanghai、亚洲上海)、JST=(Asia/Tokyo、亚洲东京)、 如:ART=(Africa/Cairo、非洲开罗)、CST=(America/Chicago、美国芝加哥) '2:创建时区' static ZoneId of(String zoneId) 从一个时区ID字符串中获取一个ZoneId实例。 static ZoneId of(String zoneId, Map<String,String> aliasMap) 获取ZoneId的实例,使用其ID别名映射来补充标准区域ID。可用使用自带的SHORT_IDS静态Map常量。 如:ZoneId.of("CTT",ZoneId.SHORT_IDS) static ZoneId ofOffset(String prefix, ZoneOffset offset) 方法可以根据偏移量创建一个ZoneId实例。偏移类型可以通过prefix传入,但偏移类型只能传GMT、UTC、UT。 static ZoneId systemDefault() 获取当前系统的默认时区信息,我们正常获取的都是:Asia/Shanghai '3:其它方法' static Set<String> getAvailableZoneIds() 获取603个区域的ID,返回的这些区域ID都可以当作区域的参数 如:Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8, Africa/Nairobi..... abstract String getId() 获取唯一的时区ID。这个方法和toString()一样。 abstract ZoneRules getRules() 获取此ID的时区相关规则和信息,例如偏移量、夏令时调整规则等。 boolean equals(Object obj) 检查此时区ID是否等于其他时区ID。 需要注意的是:使用区域ID创建的时区和偏移创建的时区比较会返回false; 其核心比较逻辑:取两个时区的getId()返回值,并通过字符串的equals方法比较是否一样。 ZoneId normalized() 规范时区ID,尽可能ZoneOffset。但一般我看不出啥效果,因为我们写的已经是规范的时区了。 String getDisplayName(TextStyle style, Locale locale) 获取区域的文字表示形式,例如“英国时间”或“+02:00”。具体看下方代码示例。 参数说明: style:指定文字样式,可以是FULL、SHORT或NARROW中的一个,决定了返回的文字表示的详细程度。 locale:指定用于本地化显示的区域设置,确定了语言和地区特定的文字显示方式。 示例: zone3.getDisplayName(TextStyle.FULL, Locale.CHINA); 打印:中国时间 static ZoneId from(TemporalAccessor temporal) 从TemporalAccessor对象中提取时区信息并返回对应的ZoneId实例;TemporalAccessor是一个接口, 它提供了访问日期时间字段值的通用方式,例如LocalDateTime、ZonedDateTime等都实现了这个接口。 注意:如ZonedDateTime是可用提取时区的,但是如LocalDateTime是不包含时区信息的,强行提取会报错。 '========================= 关于ZoneId抽象类的ZoneOffset实现类说明;=========================' '1:静态常量' static ZoneOffset MAX 最大支持偏移量的常数。返回:+18:00 static ZoneOffset MIN 最大支持偏移量的常数。返回:-18:00 static ZoneOffset UTC UTC的时区偏移量。返回:Z;这个Z也被称为0时区。 '2:创建时区' static ZoneOffset of(String offsetId) 使用时区偏移量ID字符串创建ZoneOffset实例。 static ZoneOffset ofHours(int hours) static ZoneOffset ofHoursMinutes(int hours, int minutes) static ZoneOffset ofHoursMinutesSeconds(int hours, int minutes, int seconds) static ZoneOffset ofTotalSeconds(int totalSeconds) 根据小时(hours)、分钟(minutes)、秒数(seconds)、总秒数(totalSeconds)来构建ZoneOffset对象。 '3:常用获取方法' int get(TemporalField field) long getLong(TemporalField field) 从指定的偏移量获取指定字段的值。两个方法一样,只不过返回的参数有int或者long两种。 可选择的TemporalField值有:ChronoField.OFFSET_SECONDS int getTotalSeconds() 获取区域偏移量,并转换为秒返回。和 get(ChronoField.OFFSET_SECONDS)返回的一样。 String getId() 获取唯一的时区ID。这个方法和toString()一样。 ZoneRules getRules() 获取此ID的时区相关规则和信息,例如偏移量、夏令时调整规则等。 4:比较相同或比大小 boolean equals(Object obj) 检查这个偏移量是否等于另一个偏移量。 int compareTo(ZoneOffset other) 将此偏移量与其他偏移量按降序进行比较。 注:返回0代表相同,负数代表左比右大,正数代表右比左大 '5:其它方法' boolean isSupported(TemporalField field) 检查指定的字段是否受支持。其实这里只支持:。 ValueRange range(TemporalField field) 获取指定字段的有效值的范围。只有一种使用方式:xx.range(ChronoField.OFFSET_SECONDS) static ZoneOffset from(TemporalAccessor temporal) 和上面的ZoneId介绍的方法使用方式一致。 <R> R query(TemporalQuery<R> query) 使用指定的查询查询此偏移量。具体查看query()方法详讲。 Temporal adjustInto(Temporal temporal) 调整指定的时间对象与此对象的偏移量相同。

(四):关于ZoneId基本使用

 

java

代码解读

复制代码

public static void main(String[] args) { // ============================= 两种类型参数创建时区的区别 ============================= // 使用 区域 创建时区信息 ZoneId zone1 = ZoneId.of("Asia/Shanghai"); // 使用 偏移 创建时区信息 ZoneId zone2 = ZoneId.of("+08:00"); System.out.println("时区打印:" + zone1); // 时区打印:Asia/Shanghai System.out.println("时区打印:" + zone2); // 时区打印:+08:00 System.out.println("zone1实现类:" + zone1.getClass()); // class java.time.ZoneRegion System.out.println("zone2实现类:" + zone2.getClass()); // class java.time.ZoneOffset // ================================ 创建时区的几种方式 ================================ // 下面这四个的区域或者偏移都是表示一个地方 ZoneId zone3 = ZoneId.of("Asia/Shanghai"); // Asia/Shanghai ZoneId zone4 = ZoneId.of("+08:00"); // +08:00 ZoneId zone5 = ZoneId.of("CTT", ZoneId.SHORT_IDS); // Asia/Shanghai ZoneId zone6 = ZoneId.ofOffset("GMT", ZoneOffset.of("+08:00")); // GMT+08:00 // =================================== 其它使用方式 =================================== // 获取时区的详细信息;我们可用借助ZoneRules来做其它操作 ZoneRules rules = zone3.getRules(); System.out.println(rules); // ZoneRules[currentStandardOffset=+08:00] // Asia/Shanghai 和 Asia/Shanghai 比较相同 System.out.println(zone3.equals(zone5)); // true // +08:00 和 GMT+08:00 比较不相同 System.out.println(zone4.equals(zone6)); // false // 获取区域的文字表示形式 ZoneId zone7 = ZoneId.of("Asia/Shanghai"); ZoneId zone8 = ZoneId.of("Asia/Tokyo"); // 以中文显示 System.out.println(zone7.getDisplayName(TextStyle.FULL, Locale.CHINA));// 中国时间 System.out.println(zone8.getDisplayName(TextStyle.FULL, Locale.CHINA));// 日本时间 // 以日文显示(发现小日子过的不错的日本一些文字和中文繁体一样) System.out.println(zone7.getDisplayName(TextStyle.FULL, Locale.JAPAN));// 中国時間 System.out.println(zone8.getDisplayName(TextStyle.FULL, Locale.JAPAN));// 日本時間 // 从带有时区的类中获取时区 ZonedDateTime zonedDateTime = ZonedDateTime.now(); // LocalDateTime localDateTime = LocalDateTime.now(); 这个类不包含时区哟 ZoneId from = ZoneId.from(zonedDateTime); System.out.println(from); // Asia/Shanghai }

(五):关于ZoneOffset基本使用

 

java

代码解读

复制代码

public static void main(String[] args) { // ================================ 创建时区的几种方式 ================================ // 关于几种时区偏移量ID字符串的写法 // +代表比格林时间早,-代表比格林时间晚; ZoneOffset z1 = ZoneOffset.of("+08"); // +08:00 // 这种的 "+08" 可以直接写成 "+8" ZoneOffset z2 = ZoneOffset.of("+08:30");// +08:30 // 这种的 "+08:30" 可直接写成+0830;一定要保证四位数,比如+830是不行的。 ZoneOffset z3 = ZoneOffset.of("-08:30:45"); // -08:30:45 // 这种的 "+08:30:15" 可直接写成+083045;一定要保证六位数。 // 关于使用指定时分秒创建的时区偏移的时分秒必须符号(+,-)必须一致。 ZoneOffset z4 = ZoneOffset.ofHoursMinutesSeconds(8, 30, 45); // +08:30:45 ZoneOffset z5 = ZoneOffset.ofHoursMinutesSeconds(-8, -30, -45); // -08:30:45 // =================================== 时区的比较 =================================== ZoneOffset zoneOffset1 = ZoneOffset.of("+08:00"); ZoneOffset zoneOffset2 = ZoneOffset.of("+01:00"); ZoneOffset zoneOffset3 = ZoneOffset.of("+01:00"); System.out.println(zoneOffset3.equals(zoneOffset2)); // true System.out.println(zoneOffset1.equals(zoneOffset2)); // false System.out.println(zoneOffset2.compareTo(zoneOffset3)); // 0 System.out.println(zoneOffset2.compareTo(zoneOffset1)); // 25200 System.out.println(zoneOffset1.compareTo(zoneOffset2)); // -25200 // 关于ZoneOffset的比较方法说明:返回0代表相同,负数代表左比右大,正数代表右比左大 // =================================== 其它的方法 =================================== // 从一个带时区的日期时间中提取时区偏移 ZonedDateTime zonedDateTime = ZonedDateTime.now(); ZoneOffset offset = ZoneOffset.from(zonedDateTime); System.out.println(offset); // +08:00 }

九:Instant具体时刻

  Java 8 中引入了一个Instant类,用于 表示时间线上的一个具体时刻 ,它是以Unix时间戳的形式存储,精确到纳秒(在旧版的Date类中则精确到毫秒)。其实使用纳秒去表示一个时间,其内部是由一个long字段(记录秒)和一个int字段(记录纳秒)组成,第一个部分保存的是Unix时间戳(就是1970-01-01T00:00:00Z)开始到现在的秒数,第二部分保存的是纳秒数(永远不会超过999,999,999,若加1就进位变为1秒)。我们需要知道在Instant类中只表示一个特定的时刻,不受时区影响。而且它也是一个不可变的类哟,一旦创建后则无法继续修改,这样保证了线程的安全性。
  比如创建具体时刻:Instant.ofEpochSecond(2,1); 打印:1970-01-01T00:00:02.000000001Z;我们需要知道的是Instant类在保存“1970-01-01T00:00:02”则是转换为秒存放在一个long类型的seconds字段中,而存放后面的纳秒“000000001”则是放在int类型的nanos字段里,为此这个时刻便被存储了起来。
注:一定要知道𝐼𝑛𝑠𝑡𝑎𝑛𝑡是没有时区概念的。注:一定要知道Instant是没有时区概念的。

(一):方法列表

点开查看详情:Instant时刻方法列表

 

(二):常用方法讲解

点开查看详情:Instant时刻方法详解

 

十:Clock时钟类

  在 Java 8 里的 java.time 包中引入了一个Clock时钟抽象类,用来记录当前时间时,这个类并没有记录具体的年月日和时分秒信息,而是记录了当前时间距离时间原点(1970-01-01T00:02:00)的毫秒数,同时这个时钟类还自动与系统默认时区相关联;所以有了时间毫秒和时区信息的话就能把Clock对象转换成各种日期时间类的对象。Clock抽象类的主要作用就是为日期和时间提供一个时钟,可以用于替代系统默认的时钟来进行日期和时间的操作。其次Clock里的所有实现是线程安全的类。

 

js

代码解读

复制代码

'Java中的Clock类是一个抽象类,具体内部实现类如下:' SystemClock【默认实现】:使用系统默认的时区来获取当前的日期和时间信息。 OffsetClock:表示了一个相对于UTC的固定偏移量。 TickClock:根据指定的时钟和时钟周期产生一个周期性的时间序列。 FixedClock:表示一个固定的时间点,通常用于测试或模拟特定时间的场景。

(一):方法列表

点击查看详情:Clock时钟方法列表

 

(二):常用方法讲解

点击查看详情:Clock时钟的基本方法详解

 

十一:ZonedDateTime日期时间(时区)

  Java 8 引入了 ZonedDateTime 类,用于表示 带有时区信息的日期和时间 。内部其实是由三个类组成:LocalDateTime、ZoneOffset、ZoneId;在这里的ZoneOffset是用来处理夏令时的;
  注意ZonedDateTime是不可变的,一旦创建后,其值不能更改,这有助于线程安全和更可靠的时间处理。

(一):方法列表

  其实ZonedDateTime方法使用起来也很简单,记住如下几点:以now开头的一般是创建当前日期、以of开头的一般是创建指定日期、以get开头的一般是获取日期时间分量、以with开头的一般是修改日期时间分量、以plus开头的一般是增加指定日期时间、以minus开头的一般是减少指定日期时间、以to开头的一般是转换指定类型格式;其它的也就没啥了。具体的可以参考如上的LocalDateTime。下面我只介绍一些特有的方法。

点击查看详情:关于ZonedDateTime对象的基本方法

 

(二):常用方法讲解

1:带时区的日期时间创建:1:带时区的日期时间创建:

点击查询详情:带时区的日期时间创建

 

2:时区日期时间的其它使用:2:时区日期时间的其它使用:

点击查看详情:关于时区日期时间的其它使用

 

十二:OffsetDateTime日期时间(偏移)

  Java 8 引入了 OffsetDateTime 类。它表示具有特定时区偏移量的日期和时间。其内部由两个类组成,分别为:LocalDateTime、ZoneOffset。ZoneOffset包含一个与UTC的偏移量,这个偏移量可以是正数(东经时间)或负数(西经时间)。需要注意的是这个类是不可变的,一旦创建则不能更改。

𝑂𝑓𝑓𝑠𝑒𝑡𝐷𝑎𝑡𝑒𝑇𝑖𝑚𝑒和𝑍𝑜𝑛𝑒𝑑𝐷𝑎𝑡𝑒𝑇𝑖𝑚𝑒区别:OffsetDateTime和ZonedDateTime区别:

 

js

代码解读

复制代码

OffsetDateTime和ZonedDateTime都可以表示偏差信息,那么它们具体啥区别,其实有些细微差别: OffsetDateTime 日期时间(偏移): 1:表示的是日期和时间,以及与UTC的偏移量。它不依赖于特定的时区,而是依赖于一个固定的时区偏移量。 2:它主要用于处理不依赖于特定地理时区的时间戳。 3:偏移量表示的范围是从-24:00到24:00,因为它只表示偏移量,不考虑实际的时区。 ZonedDateTime 日期时间(时区): 1:它结合了LocalDateTime、ZoneId,其中ZoneId用于表示特定的地理时区,依赖于特定的时区ID。 2:它用于处理依赖于特定地理时区的时间戳。 3:时区ID必须是一个合法的特定时区,比如“Asia/Shanghai”;它无法创建偏移几分几秒。 一般整点偏移如"GMT+08:00"都可用使用指定的时区ID代替如"Asia/Shanghai"; 但是偏移时差如"GMT+08:15"貌似ZonedDateTime就无法代替了。 所有总结:OffsetDateTime可以创建更精准的时间偏移信息,而ZonedDateTime只能创建一些整点时区ID的时间。

(一):方法列表

  其实它的方法和上面说的ZonedDateTime基本上一模一样,下面我按照特殊的方法来简单说明,其它的就可以参考ZonedDateTime来学习使用。

点开查看详情:关于OffsetDateTime对象的基本方法

 

(二):基本使用

点开查看详情:关于OffsetDateTime对象的基本使用

 

结尾END

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值