Java 的 java.time 包详解

Java 的java.time包详解

引言

在Java 8之前,处理日期和时间一直是开发者的一大痛点。Java 8引入了新的日期和时间API,即java.time包,极大地简化了日期和时间的处理。本文将详细介绍java.time包的各个组成部分及其使用方法。

1. java.time包概述

java.time包提供了一组全新的类,用于处理日期、时间、时区和时间间隔。与旧的java.util.Datejava.util.Calendar类相比,java.time包中的类是不可变且线程安全的,基于ISO-8601日历系统。

1.1 核心类

  • LocalDate: 表示没有时区的日期,例如2007-12-03
  • LocalTime: 表示没有时区的时间,例如10:15:30
  • LocalDateTime: 表示没有时区的日期和时间,例如2007-12-03T10:15:30
  • ZonedDateTime: 表示带时区的日期和时间,例如2007-12-03T10:15:30+01:00[Europe/Paris]
  • OffsetDateTime: 表示带偏移量的日期和时间,例如2007-12-03T10:15:30+01:00
  • OffsetTime: 表示带偏移量的时间,例如10:15:30+01:00
  • Instant: 表示时间线上的一个瞬时点,例如2007-12-03T10:15:30Z
  • Duration: 表示时间的持续时间,例如PT20.345S
  • Period: 表示日期的时间段,例如P1Y2M3D

2. LocalDate

LocalDate类表示没有时区的日期,通常用于表示生日、假期等。

2.1 创建LocalDate实例

LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2024, Month.JANUARY, 1);
LocalDate parsedDate = LocalDate.parse("2024-01-01");

2.2 LocalDate的常用方法

  • 获取日期信息:
    int year = today.getYear();
    Month month = today.getMonth();
    int dayOfMonth = today.getDayOfMonth();
    DayOfWeek dayOfWeek = today.getDayOfWeek();
    
  • 日期运算:
    LocalDate tomorrow = today.plusDays(1);
    LocalDate previousMonthSameDay = today.minus(1, ChronoUnit.MONTHS);
    

3. LocalTime

LocalTime类表示没有时区的时间,通常用于表示一天中的某个时间点。

3.1 创建LocalTime实例

LocalTime now = LocalTime.now();
LocalTime specificTime = LocalTime.of(10, 15, 30);
LocalTime parsedTime = LocalTime.parse("10:15:30");

3.2 LocalTime的常用方法

  • 获取时间信息:
    int hour = now.getHour();
    int minute = now.getMinute();
    int second = now.getSecond();
    
  • 时间运算:
    LocalTime oneHourLater = now.plusHours(1);
    LocalTime tenMinutesEarlier = now.minusMinutes(10);
    

4. LocalDateTime

LocalDateTime类表示没有时区的日期和时间,通常用于表示具体的时间点。

4.1 创建LocalDateTime实例

LocalDateTime now = LocalDateTime.now();
LocalDateTime specificDateTime = LocalDateTime.of(2024, Month.JANUARY, 1, 10, 15, 30);
LocalDateTime parsedDateTime = LocalDateTime.parse("2024-01-01T10:15:30");

4.2 LocalDateTime的常用方法

  • 获取日期和时间信息:
    LocalDate date = now.toLocalDate();
    LocalTime time = now.toLocalTime();
    
  • 日期和时间运算:
    LocalDateTime nextWeek = now.plusWeeks(1);
    LocalDateTime previousYear = now.minusYears(1);
    

5. ZonedDateTime

ZonedDateTime类表示带时区的日期和时间,通常用于跨时区的时间处理。

5.1 创建ZonedDateTime实例

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime specificZonedDateTime = ZonedDateTime.of(2024, 1, 1, 10, 15, 30, 0, ZoneId.of("Europe/Paris"));
ZonedDateTime parsedZonedDateTime = ZonedDateTime.parse("2024-01-01T10:15:30+01:00[Europe/Paris]");

5.2 ZonedDateTime的常用方法

  • 获取时区信息:
    ZoneId zone = now.getZone();
    ZonedOffset offset = now.getOffset();
    
  • 时区转换:
    ZonedDateTime utcDateTime = now.withZoneSameInstant(ZoneOffset.UTC);
    ZonedDateTime newYorkDateTime = now.withZoneSameInstant(ZoneId.of("America/New_York"));
    

6. OffsetDateTime

OffsetDateTime类表示带偏移量的日期和时间,通常用于表示与UTC时间的偏移。

6.1 创建OffsetDateTime实例

OffsetDateTime now = OffsetDateTime.now();
OffsetDateTime specificOffsetDateTime = OffsetDateTime.of(2024, 1, 1, 10, 15, 30, 0, ZoneOffset.of("+01:00"));
OffsetDateTime parsedOffsetDateTime = OffsetDateTime.parse("2024-01-01T10:15:30+01:00");

6.2 OffsetDateTime的常用方法

  • 获取偏移量信息:
    ZoneOffset offset = now.getOffset();
    
  • 偏移量转换:
    OffsetDateTime utcOffsetDateTime = now.withOffsetSameInstant(ZoneOffset.UTC);
    

7. Instant

Instant类表示时间线上的一个瞬时点,通常用于时间戳。

7.1 创建Instant实例

Instant now = Instant.now();
Instant specificInstant = Instant.ofEpochMilli(1609459200000L);
Instant parsedInstant = Instant.parse("2024-09-01T00:00:00Z");

7.2 Instant的常用方法

  • 获取时间戳信息:
    long epochMilli = now.toEpochMilli();
    
  • 时间戳运算:
    Instant oneHourLater = now.plus(1, ChronoUnit.HOURS);
    Instant tenMinutesEarlier = now.minus(10, ChronoUnit.MINUTES);
    

8. Duration

Duration类表示时间的持续时间,通常用于计算两个时间点之间的差异。

8.1 创建Duration实例

Duration duration = Duration.ofHours(1);
Duration parsedDuration = Duration.parse("PT1H");

8.2 Duration的常用方法

  • 获取持续时间信息:
    long seconds = duration.getSeconds();
    long nanos = duration.getNano();
    
  • 持续时间运算:
    Duration twoHoursLater = duration.plusHours(1);
    Duration tenMinutesEarlier = duration.minusMinutes(10);
    

8.3 Duration的其他方法

  • 计算两个时间点之间的持续时间:

    Instant start = Instant.parse("2024-01-01T10:15:30.00Z");
    Instant end = Instant.parse("2024-01-01T12:15:30.00Z");
    Duration duration = Duration.between(start, end);
    long hours = duration.toHours(); // 2 hours
    
  • Duration转换为其他单位:

    long minutes = duration.toMinutes(); // 120 minutes
    long millis = duration.toMillis(); // 7200000 milliseconds
    
  • 比较两个Duration对象:

    Duration duration1 = Duration.ofHours(1);
    Duration duration2 = Duration.ofMinutes(60);
    boolean isEqual = duration1.equals(duration2); // true
    
  • 获取绝对值:

    Duration negativeDuration = Duration.ofHours(-2);
    Duration positiveDuration = negativeDuration.abs(); // PT2H
    
  • 除法和乘法运算:

    Duration dividedDuration = duration.dividedBy(2); // PT1H
    Duration multipliedDuration = duration.multipliedBy(2); // PT4H
    
  • 添加和减去Duration:

    Duration addedDuration = duration.plus(Duration.ofMinutes(30)); // PT2H30M
    Duration subtractedDuration = duration.minus(Duration.ofMinutes(30)); // PT1H30M
    

9. Period

Period类表示日期的时间段,通常用于计算两个日期之间的差异。

9.1 创建Period实例

Period period = Period.ofYears(1);
Period parsedPeriod = Period.parse("P1Y");

9.2 Period的常用方法

  • 获取时间段信息:

    int years = period.getYears();
    int months = period.getMonths();
    int days = period.getDays();
    
  • 时间段运算:

    Period twoYearsLater = period.plusYears(1);
    Period tenMonthsEarlier = period.minusMonths(10);
    
  • 计算两个日期之间的时间段:

    LocalDate startDate = LocalDate.of(2023, 1, 1);
    LocalDate endDate = LocalDate.of(2024, 1, 1);
    Period periodBetween = Period.between(startDate, endDate);
    
  • Period转换为总天数:

    long totalDays = periodBetween.toTotalMonths() * 30 + periodBetween.getDays();
    
  • 解析和格式化Period:

    Period parsedPeriod = Period.parse("P1Y2M3D");
    String formattedPeriod = parsedPeriod.toString(); // P1Y2M3D
    

10. ZoneIdZoneOffset

ZoneId类表示时区ID,例如Europe/ParisZoneOffset类表示与UTC的时区偏移,例如+02:00

10.1 创建ZoneIdZoneOffset实例

ZoneId zoneId = ZoneId.of("Europe/Paris");
ZoneOffset zoneOffset = ZoneOffset.of("+02:00");

10.2 ZoneIdZoneOffset的常用方法

  • 获取系统默认时区:
    ZoneId systemDefault = ZoneId.systemDefault();
    
  • 时区转换:
    ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId);
    OffsetDateTime offsetDateTime = OffsetDateTime.now(zoneOffset);
    

11. Clock

Clock类提供了对当前时间和日期的访问,使用指定的时区。

11.1 创建Clock实例

Clock clock = Clock.systemDefaultZone();
Clock utcClock = Clock.systemUTC();
Clock fixedClock = Clock.fixed(Instant.now(), ZoneId.of("Europe/Paris"));

11.2 Clock的常用方法

  • 获取当前时间:
    Instant instant = clock.instant();
    ZonedDateTime zonedDateTime = ZonedDateTime.now(clock);
    

12. TemporalAdjuster接口

TemporalAdjuster接口用于执行复杂的日期操作,例如调整到下一个工作日。

12.1 使用TemporalAdjuster

LocalDate nextSunday = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
LocalDate firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());

13. DateTimeFormatter

DateTimeFormatter类用于格式化和解析日期时间对象。

13.1 创建DateTimeFormatter实例

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

13.2 DateTimeFormatter的常用方法

  • 格式化日期时间:
    String formattedDateTime = LocalDateTime.now().format(formatter);
    
  • 解析日期时间:
    LocalDateTime dateTime = LocalDateTime.parse("2024-01-01 10:15:30", formatter);
    

14. java.time.temporal

java.time.temporal包提供了更底层的日期时间操作接口和类,例如TemporalTemporalAmountTemporalUnit等。

14.1 Temporal接口

Temporal接口定义了日期时间对象的基本操作,例如加减时间单位。

14.2 TemporalAmount接口

TemporalAmount接口表示时间量,例如DurationPeriod

14.3 TemporalUnit接口

TemporalUnit接口表示时间单位,例如天、小时、分钟等。

15. java.time.chrono

java.time.chrono包提供了对非ISO-8601日历系统的支持,例如日本历、泰国历等。

15.1 ChronoLocalDate接口

ChronoLocalDate接口表示日历系统中的日期。

15.2 ChronoLocalDateTime接口

ChronoLocalDateTime接口表示日历系统中的日期和时间。

15.3 ChronoZonedDateTime接口

ChronoZonedDateTime接口表示带时区的日期和时间。

16. java.time.format

java.time.format包提供了格式化和解析日期时间的类和接口。

16.1 DateTimeFormatter

DateTimeFormatter类用于格式化和解析日期时间对象。

16.2 DateTimeFormatterBuilder

DateTimeFormatterBuilder类用于构建复杂的日期时间格式化器。

16.3 ResolverStyle枚举

ResolverStyle枚举定义了解析日期时间字符串时的策略,例如严格模式、宽松模式等。

17. java.time.zone

java.time.zone包提供了对时区规则的支持。

17.1 ZoneRules

ZoneRules类表示时区的规则,例如夏令时的开始和结束时间。

17.2 ZoneRulesProvider

ZoneRulesProvider类提供了获取时区规则的方法。

结论

Java 8引入的java.time包极大地简化了日期和时间的处理。通过使用不可变和线程安全的类可以更轻松地进行日期和时间的操作。

猜你喜欢

转载自blog.csdn.net/Li_WenZhang/article/details/142182778