图片来源:https://www.cnblogs.com/yourbatman/p/14324575.html
一. LocalDate和LocalTime
LocalDate:代表不含时区信息的日期,它只能表示年、月、日。它适用于记录一个日子,比如生日、纪念日、或者任何只需要日期而不需要具体时间的场合。
LocalTime
:代表不含日期和时区的时间,它只能表示小时、分钟、秒和纳秒。它适用于记录一天中的具体时间点,比如起床时间、会议开始时间等。
LocalDate相关方法
// 获取当前日期
LocalDate today = LocalDate.now();
System.out.println("当前日期:"+today);// 创建指定日期
LocalDate birthday = LocalDate.of(2024, Month.SEPTEMBER, 18);
System.out.println("创建指定日期:"+birthday);// 格式化日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formattedDate = birthday.format(formatter);
System.out.println(formattedDate);// 解析日期
LocalDate parsedDate = LocalDate.parse("2025-09-18", formatter);
System.out.println(parsedDate);
LocalTime相关方法
// 获取当前时间
LocalTime now = LocalTime.now();
System.out.println("当前时间:"+now);// 创建指定时间
LocalTime dinnerTime = LocalTime.of(18, 30);
System.out.println("创建指定时间:"+dinnerTime);// 格式化时间
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
String formattedTime = dinnerTime.format(timeFormatter);
System.out.println(formattedTime);// 解析时间
LocalTime parsedTime = LocalTime.parse("18:30:00", timeFormatter);
System.out.println(parsedTime);
LocalDate和LocalTime的结合
// 结合日期和时间
LocalDateTime dateAndTime = LocalDateTime.of(birthday, dinnerTime);// 获取完整的日期时间
LocalDateTime nowDateTime = LocalDateTime.now();
关于格式化和解析时间的注意事项
-
模式字符串:在DateTimeFormatter.ofPattern方法中使用的模式字符串必须与日期时间字符串的结构相匹配。例如,"yyyy-MM-dd HH:mm:ss"模式字符串表示一个包含四位年份、两位月份、两位日期、两位小时(24小时制)、两位分钟和两位秒的字符串。
-
异常处理:在解析日期时间时,如果模式字符串与输入字符串不匹配,会抛出DateTimeParseException。
-
时区:LocalDateTime和LocalDate类不包含时区信息。如果你需要处理时区,可以使用ZonedDateTime类。
使用场景
- LocalDate:当你需要处理与时间无关的日期数据时,比如安排日程、记录事件日期等。
- LocalTime:当你需要记录一天中的具体时刻,比如设定闹钟、安排会议时间等。
- 结合使用:当你需要同时处理日期和时间,比如记录一个事件的具体发生时间。
二. ZoneOffset和ZoneId
ZoneOffset: 代表了一个固定的时区偏移量,它相对于协调世界时(UTC)。使用 ZoneOffset 就像是在 UTC 时间上加上或减去一定的小时和分钟数。
ZoneId
:代表了一个时区标识符,它不仅包括固定的偏移量,还可能包括夏令时(Daylight Saving Time, DST)规则。使用 ZoneId 意味着您正在处理一个具体的时区,它可能会根据当地的法律或规定而改变其偏移量。
如果有一个 UTC 时间,并且知道某个地区相对于 UTC 有 +8 小时的偏移(如北京时间),可以使用 ZoneOffset 来表示这个偏移。通过将这个偏移量加到 UTC 时间上,可以获得该地区的本地时间。
如果想将北京时间(Asia/Shanghai)切换到伦敦时间(Europe/London),可以使用 ZoneId 来实现。这不仅涉及到偏移量的更改,还可能涉及到夏令时的调整。
代码示例
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);// 使用 ZoneOffset 转换为北京时间
ZonedDateTime beijingTime = localDateTime.atZone(ZoneOffset.ofHours(+8));
System.out.println("北京时间: " + beijingTime);// 使用 ZoneId 转换为伦敦时间,包括夏令时规则
ZonedDateTime londonTime = localDateTime.atZone(ZoneId.of("Europe/London"));
System.out.println("伦敦时间: " + londonTime);
ZoneOffset.ofHours(+8) 表示东八区的固定偏移,而 ZoneId.of("Europe/London") 表示伦敦的时区,它会自动考虑夏令时的变化
总结
ZoneOffset 更适合于简单的时间偏移操作。
ZoneId 更适合于需要考虑时区规则和夏令时的场景。
三. LocalDateTime,OffsetDateTime和ZonedDateTime
类 | LocalDateTime | OffsetDateTime | ZonedDateTime |
---|---|---|---|
定义 | 表示没有时区信息的日期和时间,它仅包含年、月、日、小时、分钟、秒和纳秒。 | 包含时区信息,但表示的是相对于UTC/Greenwich的偏移量(例如,+02:00, -08:00)。它包含LocalDateTime的信息和一个时区偏移量。 | 包含时区信息的日期时间。它不仅包含LocalDateTime的所有信息,还包含时区ID(例如,Europe/Paris, America/New_York)。 |
用途 | 适用于记录本地日期和时间,但不包含任何有关时区的信息。例如,记录一个事件的开始时间,而不需要考虑时区差异。 | 适用于需要明确UTC偏移量的场景,例如,航空时间表、跨国数据交换等。 | 适用于需要考虑时区的场景,如跨国会议时间的安排、用户在不同地区的登录时间记录等。 |
LocalDateTime相关方法
//获取当前日期和时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now);//根据指定日期和时间创建
LocalDateTime dateTime = LocalDateTime.of(2024, Month.MAY, 19, 15, 30);
System.out.println(dateTime);//格式化和解析日期时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = formatter.format(dateTime);
String parsed = dateTime.format(formatter);//计算日期时间的差值
Duration duration = Duration.between(dateTime, now);
long hoursBetween = duration.toHours();
System.out.println(hoursBetween);
OffsetDateTime相关方法
//获取当前日期和时间,指定UTC偏移量
OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
System.out.println(now);//根据指定日期、时间和UTC偏移量创建OffsetDateTime
OffsetDateTime offsetDateTime = OffsetDateTime.of(LocalDateTime.of(2024, Month.MAY, 29, 15, 30), ZoneOffset.ofHours(2));
System.out.println(offsetDateTime);//转换UTC偏移量
OffsetDateTime withNewOffset = offsetDateTime.withOffsetSameInstant(ZoneOffset.ofHours(-5));
System.out.println(withNewOffset);
ZonedDateTime相关方法
//获取当前日期和时间,指定时区
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println(now);//根据指定日期、时间和时区创建ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.of(2024, Month.MAY, 29, 15, 30), ZoneId.of("Europe/Paris"));
System.out.println(zonedDateTime);//转换时区
ZonedDateTime inNewYork = zonedDateTime.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(inNewYork);//获取时区信息
ZoneId zone = zonedDateTime.getZone();
String zoneId = zone.getId();
System.out.println(zoneId);