4.5java日期类

 

目录

旧的日期时间 API

1. java.util.Date

2. java.util.Calendar

新的日期时间 API(Java 8+)

1. java.time.LocalDate

2. java.time.LocalTime

3. java.time.LocalDateTime

4. java.time.ZonedDateTime

Instant对象

获取时间戳

时间计算

与其他日期时间类型的转换

DateTimeFormatter

Duration

创建 Duration 对象

获取 Duration 中的值

对 Duration 进行操作

Period

创建 Period 对象

获取 Period 中的值

对 Period 进行操作

总结

新旧日期时间 API 对比


在 Java 中,处理日期和时间的类随着版本的发展有不同的体系。早期版本主要使用 java.util.Datejava.util.Calendar 等类,Java 8 及以后引入了新的日期和时间 API(JSR 310),包含在 java.time 包中。

甲骨文官方文档

Overview (Java SE 21 & JDK 21)

JDK中文文档。https://java.cunzaima.cn/jdk21/doc-zh/api/index.html

旧的日期时间 API

1. java.util.Date
  • 概述Date 类表示特定的瞬间,精确到毫秒。不过它的很多方法在 Java 1.1 之后已经被弃用,因为其设计存在一些问题,比如线程不安全、缺乏时区支持等。
  • 常用方法
    • Date():创建一个表示当前时间的 Date 对象。
    • Date(long date):根据给定的毫秒数创建 Date 对象,该毫秒数是从 1970 年 1 月 1 日 00:00:00 GMT 开始计算的。
    • getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
    • equals(Object obj):比较两个 Date 对象是否相等。
import java.util.Date;

public class DateExample {
    public static void main(String[] args) {
        // 创建表示当前时间的 Date 对象
        Date currentDate = new Date();
        System.out.println("当前时间: " + currentDate);

        // 根据毫秒数创建 Date 对象
        long milliseconds = 1609459200000L;
        Date specificDate = new Date(milliseconds);
        System.out.println("指定时间: " + specificDate);

        // 获取毫秒数
        long timeInMillis = currentDate.getTime();
        System.out.println("当前时间的毫秒数: " + timeInMillis);

        // 比较两个 Date 对象
        boolean isEqual = currentDate.equals(specificDate);
        System.out.println("两个日期是否相等: " + isEqual);
    }
}
2. java.util.Calendar
  • 概述Calendar 是一个抽象类,用于在 Java 中进行日期和时间的计算。它提供了一些方法来获取和设置年、月、日、时、分、秒等信息,并且支持时区和本地化。
  • 常用方法
    • Calendar.getInstance():获取一个 Calendar 实例,该实例使用默认时区和语言环境。
    • get(int field):获取指定字段的值,例如 Calendar.YEARCalendar.MONTH 等。
    • set(int field, int value):设置指定字段的值。
    • add(int field, int amount):对指定字段进行加减操作。
import java.util.Calendar;

public class CalendarExample {
    public static void main(String[] args) {
        // 获取 Calendar 实例
        Calendar calendar = Calendar.getInstance();

        // 获取年、月、日
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // 月份从 0 开始,所以要加 1
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println("当前日期: " + year + "-" + month + "-" + day);

        // 设置日期
        calendar.set(Calendar.YEAR, 2025);
        calendar.set(Calendar.MONTH, Calendar.JUNE);
        calendar.set(Calendar.DAY_OF_MONTH, 15);
        System.out.println("设置后的日期: " + calendar.getTime());

        // 日期加减操作
        calendar.add(Calendar.DAY_OF_MONTH, 5);
        System.out.println("加 5 天后的日期: " + calendar.getTime() +"\t"
+  calendar.getTime().getTime()+"\t"+  calendar.getTimeInMillis()  +"\t"
+  calendar.getTimeZone().getOffset(calendar.getTimeInMillis()));
        // 设置时区
        TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
        calendar.setTimeZone(timeZone);
        System.out.println("美国纽约的日期: " + calendar.getTime() +"\t"
+  calendar.getTime().getTime()  +"\t"+ calendar.getTimeInMillis() +"\t"
+  calendar.getTimeZone().getOffset(calendar.getTimeInMillis()));
 
    }
}
  • SimpleDateFormat:用于将Date对象格式化为指定的字符串格式,或者将字符串解析为Date对象。它通过模式字符串来定义日期和时间的格式,常用的模式字符有:
    • y:年,如yyyy表示四位年份,yy表示两位年份。
    • M:月,MM表示两位数字的月份,MMM表示月份的缩写(如 Jan、Feb 等),MMMM表示月份的全称。
    • d:日,dd表示两位数字的日。
    • H:小时(24 小时制),HH表示两位数字的小时。
    • h:小时(12 小时制)。
    • m:分钟,mm表示两位数字的分钟。
    • s:秒,ss表示两位数字的秒。
    • S:毫秒。
    • z:时区,如CST

例如,SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");可以将Date对象格式化为2024-05-08 14:34:56这样的字符串。

  • java.util.CalendarCalendar类主要用于对日期和时间进行操作和计算,它本身没有直接的日期格式表示。但可以通过SimpleDateFormatCalendar对象转换为指定格式的字符串,例如:
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf.format(calendar.getTime());

        String dateString = "2024-10-01 14:30:00";

        try {
            Date date = sdf.parse(dateString);
            System.out.println("解析后的日期: " + date);
        } catch (ParseException e) {
            System.out.println("解析日期时出错: " + e.getMessage());
        }

新的日期时间 API(Java 8+)

1. java.time.LocalDate
  • 概述LocalDate 表示一个不可变的日期对象,只包含日期信息(年、月、日),不包含时间和时区信息。
  • 常用方法
    • LocalDate.now():获取当前日期。
    • LocalDate.of(int year, int month, int dayOfMonth):根据指定的年、月、日创建 LocalDate 对象。
    • getYear()getMonth()getDayOfMonth():获取年、月、日信息。
    • plusDays(long daysToAdd)minusDays(long daysToSubtract):进行日期的加减操作。
import java.time.LocalDate;

public class LocalDateExample {
    public static void main(String[] args) {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        System.out.println("当前日期: " + currentDate);

        // 根据指定的年、月、日创建 LocalDate 对象
        LocalDate specificDate = LocalDate.of(2025, 6, 15);
        System.out.println("指定日期: " + specificDate);

        // 获取日期信息
        int year = specificDate.getYear();
        int month = specificDate.getMonthValue();
        int day = specificDate.getDayOfMonth();
        System.out.println("指定日期的年: " + year + ", 月: " + month + ", 日: " + day);

        // 日期加减操作
        LocalDate newDate = specificDate.plusDays(5);
        System.out.println("加 5 天后的日期: " + newDate);
    }
}
2. java.time.LocalTime
  • 概述LocalTime 表示一个不可变的时间对象,只包含时间信息(时、分、秒、纳秒),不包含日期和时区信息。
  • 常用方法
    • LocalTime.now():获取当前时间。
    • LocalTime.of(int hour, int minute):根据指定的时、分创建 LocalTime 对象。
    • getHour()getMinute()getSecond():获取时、分、秒信息。
    • plusHours(long hoursToAdd)minusMinutes(long minutesToSubtract):进行时间的加减操作。
import java.time.LocalTime;

public class LocalTimeExample {
    public static void main(String[] args) {
        // 获取当前时间
        LocalTime currentTime = LocalTime.now();
        System.out.println("当前时间: " + currentTime);

        // 根据指定的时、分创建 LocalTime 对象
        LocalTime specificTime = LocalTime.of(14, 30);
        System.out.println("指定时间: " + specificTime);

        // 获取时间信息
        int hour = specificTime.getHour();
        int minute = specificTime.getMinute();
        System.out.println("指定时间的时: " + hour + ", 分: " + minute);

        // 时间加减操作
        LocalTime newTime = specificTime.plusHours(2);
        System.out.println("加 2 小时后的时间: " + newTime);
    }
}
3. java.time.LocalDateTime
  • 概述LocalDateTime 表示一个不可变的日期和时间对象,包含日期和时间信息(年、月、日、时、分、秒、纳秒),不包含时区信息。
  • 常用方法:结合了 LocalDate 和 LocalTime 的方法,可进行日期和时间的操作。
import java.time.LocalDateTime;

public class LocalDateTimeExample {
    public static void main(String[] args) {
        // 获取当前日期和时间
        LocalDateTime currentDateTime = LocalDateTime.now();
        System.out.println("当前日期和时间: " + currentDateTime);

        // 根据指定的日期和时间创建 LocalDateTime 对象
        LocalDateTime specificDateTime = LocalDateTime.of(2025, 6, 15, 14, 30);
        System.out.println("指定日期和时间: " + specificDateTime);

        // 日期和时间加减操作
        LocalDateTime newDateTime = specificDateTime.plusDays(2).plusHours(3);
        System.out.println("加 2 天 3 小时后的日期和时间: " + newDateTime);
    }
}
4. java.time.ZonedDateTime
  • 概述ZonedDateTime 表示一个带时区的日期和时间对象,包含日期、时间和时区信息。
  • 常用方法
    • ZonedDateTime.now():获取当前带时区的日期和时间。
    • ZonedDateTime.of(LocalDateTime localDateTime, ZoneId zone):根据 LocalDateTime 和 ZoneId 创建 ZonedDateTime 对象。
    • getZone():获取时区信息。
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class ZonedDateTimeExample {
    public static void main(String[] args) {
        // 获取当前带时区的日期和时间
        ZonedDateTime currentZonedDateTime = ZonedDateTime.now();
        System.out.println("当前带时区的日期和时间: " + currentZonedDateTime);

        // 根据 LocalDateTime 和 ZoneId 创建 ZonedDateTime 对象
        LocalDateTime localDateTime = LocalDateTime.of(2025, 6, 15, 14, 30);
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        ZonedDateTime specificZonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
        System.out.println("指定带时区的日期和时间: " + specificZonedDateTime);

        // 获取时区信息
        ZoneId zone = specificZonedDateTime.getZone();
        System.out.println("时区: " + zone);
    }
}

Instant对象

  • now方法:可以通过Instant.now()获取当前时间的Instant对象。例如,Instant instant = Instant.now();,这将返回当前时刻的Instant,精确到纳秒。
获取时间戳
  • toEpochMilli方法Instant提供了toEpochMilli方法来获取从 1970 年 1 月 1 日 00:00:00 UTC 到该Instant所表示的时间点的毫秒数。例如,long millis = instant.toEpochMilli();,可以将Instant对象转换为时间戳,方便与其他需要时间戳的系统或 API 进行交互。
  • getEpochSecond方法:获取从 1970 年 1 月 1 日 00:00:00 UTC 到该Instant所表示的时间点的秒数。例如,long seconds = instant.getEpochSecond();,如果需要以秒为单位获取时间戳,可以使用该方法。
时间计算
  • Instant可以进行时间的加减运算,通过plusminus方法来实现。例如,要获取当前时间 5 秒后的Instant,可以使用Instant futureInstant = Instant.now().plusSeconds(5);;要获取 10 分钟前的Instant,可以使用Instant pastInstant = Instant.now().minusMinutes(10);
与其他日期时间类型的转换
  • LocalDateTime转换:可以通过atZone方法将Instant转换为指定时区的LocalDateTime。例如,Instant instant = Instant.now(); LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());,这将把当前的Instant转换为系统默认时区的LocalDateTime。反之,也可以通过toInstant方法将LocalDateTime转换为Instant,例如,LocalDateTime ldt = LocalDateTime.now(); Instant instant = ldt.toInstant(ZoneOffset.UTC);,将当前的LocalDateTime转换为 UTC 时区的Instant
  • ZonedDateTime转换Instant可以直接通过atZone方法转换为ZonedDateTime,例如,Instant instant = Instant.now(); ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());,将当前的Instant转换为系统默认时区的ZonedDateTime。而ZonedDateTime也可以通过toInstant方法转换为Instant,例如,ZonedDateTime zdt = ZonedDateTime.now(); Instant instant = zdt.toInstant();

    DateTimeFormatter

    • java.time包中的格式化类:新日期时间 API 提供了DateTimeFormatter类来进行日期和时间的格式化与解析。它的模式定义与SimpleDateFormat有一些相似之处,但更加灵活和强大。常用的模式字符与SimpleDateFormat类似,例如yyyy-MM-ddHH:mm:ss等。
    • LocalDateLocalTimeLocalDateTime
      • LocalDate:表示日期,默认格式为yyyy-MM-dd,例如2024-05-08。可以使用DateTimeFormatter进行格式化,如
        LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))
        //会将当前日期格式化为08/05/2024。
      • LocalTime:表示时间,默认格式为HH:mm:ss.SSS,例如14:34:56.123。同样可以通过DateTimeFormatter进行自定义格式化。
      • LocalDateTime:表示日期和时间,默认格式为yyyy-MM-dd HH:mm:ss.SSS,例如2024-05-08 14:34:56.123。也能使用DateTimeFormatter按照需求进行格式化。
    • 综合案例:
    • import java.time.LocalDateTime;
      import java.time.format.DateTimeFormatter;
      
      public class DateTimeFormatterExample {
          public static void main(String[] args) {
              // 1. 通过模式字符串创建DateTimeFormatter
              DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
      
              // 2. 格式化当前日期时间
              LocalDateTime now = LocalDateTime.now();
              String formattedDateTime1 = formatter1.format(now);
              System.out.println("Formatted DateTime 1: " + formattedDateTime1);
      
              // 3. 使用预定义的格式创建DateTimeFormatter
              DateTimeFormatter formatter2 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
              String formattedDateTime2 = formatter2.format(now);
              System.out.println("Formatted DateTime 2: " + formattedDateTime2);
      
              // 4. 解析字符串为日期时间对象
              String dateTimeStr = "2024-05-08 12:30:00";
              LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeStr, formatter1);
              System.out.println("Parsed DateTime: " + parsedDateTime);
      
              // 5. 基于本地化创建DateTimeFormatter
              DateTimeFormatter formatter3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL)
                     .withLocale(Locale.CHINA);
              String formattedDateTime3 = formatter3.format(now);
              System.out.println("Formatted DateTime 3: " + formattedDateTime3);
          }
      }

    Duration

    Duration 类用于以秒和纳秒的方式表示时间间隔,它主要处理基于时间(小时、分钟、秒、纳秒)的时间量,适用于处理诸如程序执行时间、两个时间点之间的时间差等场景。

    创建 Duration 对象
    • Duration.between(Temporal startInclusive, Temporal endExclusive):根据两个 Temporal 对象(如 LocalTimeLocalDateTime 或 Instant)计算它们之间的时间间隔。
    import java.time.Duration;
    import java.time.LocalTime;
    
    public class DurationExample {
        public static void main(String[] args) {
            LocalTime startTime = LocalTime.of(9, 0);
            LocalTime endTime = LocalTime.of(12, 30);
            Duration duration = Duration.between(startTime, endTime);
            System.out.println("时间间隔: " + duration);
        }
    }
    • Duration.of(long amount, TemporalUnit unit):通过指定数量和时间单位来创建 Duration 对象。
    Duration duration = Duration.of(2, java.time.temporal.ChronoUnit.HOURS);
    System.out.println("自定义时间间隔: " + duration);
    

    获取 Duration 中的值

    可以使用 getSeconds() 方法获取 Duration 中的总秒数,使用 toHours()toMinutes() 等方法将其转换为不同的时间单位

    Duration duration = Duration.of(2, java.time.temporal.ChronoUnit.HOURS);
    System.out.println("总秒数: " + duration.getSeconds());
    System.out.println("总小时数: " + duration.toHours());
    
    对 Duration 进行操作
    Duration duration1 = Duration.of(1, java.time.temporal.ChronoUnit.HOURS);
    Duration duration2 = Duration.of(2, java.time.temporal.ChronoUnit.HOURS);
    Duration sumDuration = duration1.plus(duration2);
    Duration diffDuration = duration1.minus(duration2);
    System.out.println("相加后的间隔: " + sumDuration);
    System.out.println("相减后的间隔: " + diffDuration);
    

    Period

    Period 类用于以年、月、日的方式表示日期之间的间隔,它主要处理基于日期(年、月、日)的时间量,适用于处理诸如人的年龄、两个事件之间的日期差等场景。

    创建 Period 对象
    • Period.between(LocalDate startDate, LocalDate endDate):根据两个 LocalDate 对象计算它们之间的日期间隔。
    import java.time.LocalDate;
    import java.time.Period;
    
    public class PeriodExample {
        public static void main(String[] args) {
            LocalDate startDate = LocalDate.of(2020, 1, 1);
            LocalDate endDate = LocalDate.of(2023, 12, 31);
            Period period = Period.between(startDate, endDate);
            System.out.println("日期间隔: " + period);
        }
    }
    
    • Period.of(int years, int months, int days):通过指定年、月、日的值来创建 Period 对象。
    Period period = Period.of(2, 3, 10);
    System.out.println("自定义日期间隔: " + period);
    
    获取 Period 中的值

    可以使用 getYears()getMonths() 和 getDays() 方法分别获取 Period 中的年、月、日部分

    Period period = Period.of(2, 3, 10);
    System.out.println("年: " + period.getYears());
    System.out.println("月: " + period.getMonths());
    System.out.println("日: " + period.getDays());
    
    对 Period 进行操作
    • plus(Period other):将两个 Period 对象相加。
    • minus(Period other):从当前 Period 中减去另一个 Period 对象。
    • Duration.between(Temporal startInclusive, Temporal endExclusive):根据两个 Temporal 对象(如 LocalTimeLocalDateTime 或 Instant)计算它们之间的时间间隔。
    • Duration.of(long amount, TemporalUnit unit):通过指定数量和时间单位来创建 Duration 对象。
    • plus(Duration other):将两个 Duration 对象相加。
    • minus(Duration other):从当前 Duration 中减去另一个 Duration 对象。
    总结
    • Period 用于处理基于日期的时间间隔,以年、月、日为单位。
    • Duration 用于处理基于时间的时间间隔,以秒和纳秒为单位。

    新旧日期时间 API 对比

    • 线程安全性:旧的 Date 和 Calendar 类不是线程安全的,而新的日期时间 API 中的类都是不可变的,是线程安全的。
    • 易用性:新的日期时间 API 提供了更丰富的方法和更清晰的设计,使用起来更加方便。
    • 功能完整性:新的 API 对时区、日期计算等功能的支持更加完善。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    chxii

    小小打赏,大大鼓励!

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值