Java时间类

Date类

Java中的Date类是用于获取和处理日期和时间的基本工具,它位于java.util包中。

Date类的主要功能包括:

  1. 封装当前日期和时间Date类可以表示特定的瞬间,精确到毫秒。它通常用于获取系统的当前日期和时间。
  2. 构造函数Date类提供两个构造函数来创建对象。第一个无参数的构造函数创建一个表示当前日期和时间的Date对象。第二个构造函数接受一个长整型参数,表示从1970年1月1日0时0分0秒(UTC)起的毫秒数。
  3. 日期和时间操作:虽然Date类提供了一些基本的操作方法,但它并不方便进行更复杂的日期和时间处理。因此,从JDK 1.1版本开始,推荐使用Calendar类来进行这些操作。
  4. 格式化和解析:对于日期和时间的格式化和解析,可以使用DateFormat类和它的子类SimpleDateFormat。这些类提供了将日期转换为字符串以及将字符串解析为日期的功能。
  5. 国际化问题Date类不便于实现国际化,因为它依赖于默认的语言环境和时区设置。在需要处理多语言环境或时区时,应考虑使用其他更为合适的类或方法。

代码展示:

import java.util.Date;

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

        // 使用Date类的构造函数创建一个指定毫秒数的Date对象
        long milliseconds = 1625497600000L; // 2021年7月1日的时间戳(毫秒)
        Date customDate = new Date(milliseconds);
        System.out.println("自定义日期和时间: " + customDate);
    }
}

SimpleDateFormat类

 

SimpleDateFormat是Java中用于日期和时间格式化的类,它位于java.text包中。SimpleDateFormat是一个具体的类,实现了DateFormat接口。

SimpleDateFormat的主要功能包括:

  1. 格式化日期和时间:将Date对象转换为特定格式的字符串。
  2. 解析日期和时间:将符合特定格式的字符串解析为Date对象。
  3. 自定义格式:通过使用模式字母来定义日期和时间的格式。例如,"yyyy-MM-dd HH:mm:ss"表示年-月-日 时:分:秒的格式。
  4. 国际化SimpleDateFormat可以结合Locale类来实现不同语言环境的日期和时间格式化。
  5. 线程安全:从Java 1.1版本开始,SimpleDateFormat不是线程安全的,因此应避免在多线程环境中共享同一个SimpleDateFormat实例。如果需要在多线程环境下使用,可以考虑使用ThreadLocal<SimpleDateFormat>或者每次需要时创建新的实例。

以下是一个简单的示例,展示如何使用SimpleDateFormat来格式化和解析日期和时间:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatExample {
    public static void main(String[] args) {
        // 创建一个SimpleDateFormat对象,指定日期和时间的格式
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 格式化当前日期和时间
        Date currentDate = new Date();
        String formattedDate = formatter.format(currentDate);
        System.out.println("格式化后的日期和时间:" + formattedDate);

        // 解析一个日期和时间字符串
        String dateString = "2022-01-01 12:00:00";
        try {
            Date parsedDate = formatter.parse(dateString);
            System.out.println("解析后的日期和时间:" + parsedDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

上述代码首先创建了一个SimpleDateFormat对象,并指定了日期和时间的格式。然后,我们使用该格式化器将当前日期和时间格式化为字符串,并将一个符合格式的字符串解析为Date对象。请注意,parse方法可能会抛出ParseException异常,因此需要进行异常处理。

Calendar类

Java中的Calendar类是一个处理日期和时间的核心抽象类

Calendar类提供了一组方法,用于在日历字段(如YEAR、MONTH、DAY_OF_MONTH、HOUR等)与特定瞬间之间进行转换,以及执行各种日期和时间的操作。由于Calendar类是抽象的,不能直接实例化,而是通过调用其静态方法getInstance()来获取一个Calendar对象,该对象已由当前日期和时间初始化。

Calendar类的常用功能包括:

  • 获取当前日期和时间:通过调用Calendar.getInstance()可以获取一个代表当前日期和时间的Calendar对象。
  • 操作日历字段:可以使用Calendar对象中的方法来获取或设置年、月、日等日历字段的值。
  • 日期和时间计算:可以执行如计算日期差异、添加或减去时间单位等操作。

此外,Calendar类的静态常量,如Calendar.YEARCalendar.MONTHCalendar.DATECalendar.HOUR等,用于指示不同的日历字段,这些字段在处理日期和时间时非常重要。

代码展示:

import java.util.Calendar;

public class CalendarExample {
    public static void main(String[] args) {

        // 获取一个代表当前日期和时间的Calendar对象
        Calendar calendar = Calendar.getInstance();
        System.out.println("当前日期和时间:" + calendar.getTime());


        //操作日历字段
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始,所以需要加1
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        
        System.out.println("当前日期:" + year + "-" + month + "-" + day);
        System.out.println("当前时间:" + hour + ":" + minute + ":" + second);
        

        //日期和时间计算
        //添加或减去时间单位
        calendar.add(Calendar.DATE, 5); // 在当前日期上加上5天
        System.out.println("当前日期加上5天后:" + calendar.getTime());
        
        calendar.add(Calendar.MONTH, -2); // 在当前月份上减去2个月
        System.out.println("当前月份减去2个月后:" + calendar.getTime());
        
        calendar.add(Calendar.YEAR, 1); // 在当前年份上加上1年
        System.out.println("当前年份加上1年后:" + calendar.getTime());
    }
}

ZoneId类

Java中的ZoneId类是用于处理时区的类,它是java.time包的一部分

ZoneId类在Java 8中被引入,它与ZonedDateTime和Instant类一起,用于处理时区和时间戳。以下是ZoneId类的一些主要功能:

  • 创建ZoneId对象:可以使用of(String zoneId)方法根据时区标识符创建ZoneId对象。例如,ZoneId.of("Asia/Shanghai")会创建一个表示上海时区的ZoneId对象。
  • 获取所有可用的时区标识符getAvailableZoneIds()方法可以返回一个包含所有可用时区标识符的集合,这有助于在程序中列出或选择特定的时区。
  • 处理夏令时等时区变化getRules()方法获取此时区的规则,这些规则用于处理夏令时或其他时区变化的情况。
  • 序列化和反序列化:ZoneId类支持序列化,可以将区域ID以字符串形式存储或传输。即使在ID未知的Java运行时环境中,也可以反序列化ZoneId对象。
  • 与其他日期时间类配合使用:ZoneId类通常与LocalDateTime和ZonedDateTime类配合使用,以处理带有时区的日期和时间。例如,可以通过将LocalDateTime与特定的ZoneId结合,得到一个ZonedDateTime对象,这样就可以表示一个具体的日期和时间,同时包含了时区信息。

代码展示:

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Set;

public class ZoneIdExample {
    public static void main(String[] args) {
        // 创建ZoneId对象
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        System.out.println("ZoneId: " + zoneId);

        // 获取所有可用的时区标识符
        Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
        System.out.println("Available Zone IDs: " + availableZoneIds);

        // 处理夏令时等时区变化
        ZoneId.Rules rules = zoneId.getRules();
        System.out.println("Rules for " + zoneId + ": " + rules);

        // 序列化和反序列化ZoneId对象
        String serializedZoneId = zoneId.toString();
        ZoneId deserializedZoneId = ZoneId.of(serializedZoneId);
        System.out.println("Deserialized ZoneId: " + deserializedZoneId);

        // 与其他日期时间类配合使用
        ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId);
        System.out.println("Current date and time in " + zoneId + ": " + zonedDateTime);
    }
}

 上述代码演示了如何使用ZoneId类来创建、查询和管理时区。首先,我们使用ZoneId.of()方法创建一个表示上海时区的ZoneId对象。然后,我们使用ZoneId.getAvailableZoneIds()方法获取所有可用的时区标识符,并打印出来。接下来,我们使用zoneId.getRules()方法获取此时区的规则,并打印出来。然后,我们将ZoneId对象序列化为字符串,并使用ZoneId.of()方法将其反序列化为新的ZoneId对象。最后,我们使用ZonedDateTime.now()方法获取当前日期和时间,并将其与特定的ZoneId结合,得到一个ZonedDateTime对象,以表示一个具体的日期和时间,同时包含了时区信息。

Instant类

Java中的Instant类是一个用于表示时间线上的瞬时点的类,它位于java.time包中

Instant类在Java 8中被引入,作为处理日期和时间的一部分。与旧版的java.util.Date类相比,Instant提供了更高的精度,能够以纳秒为单位表示时间点。以下是一些关于Instant类的重要信息:

  • 精度和存储Instant类使用纳秒级别的精度来存储时间点,这比java.util.Date类的毫秒精度要高得多。为了实现这一点,Instant内部使用一个长整型(long)来存储纪元秒(即从1970年1月1日0时起的秒数),以及一个整数来存储纳秒部分,范围在0到999,999,999之间。
  • 创建实例:可以通过调用Instant类的静态方法now()获取当前时间的Instant实例,或者使用of()方法根据特定的纪元秒和纳秒值创建一个Instant实例。
  • 时间戳转换Instant对象可以转换为时间戳,例如,可以使用toEpochMilli()方法将其转换为毫秒级别的时间戳。同样地,也可以从一个已知的毫秒级时间戳构造出一个Instant对象。
  • 不处理日历单位Instant类主要用于处理时间戳相关的操作,它不直接处理年、月、日等日历单位。如果需要这些信息,可以将Instant对象转换为LocalDateTimeZonedDateTime等其他日期时间类。
  • 兼容性Instant.now()的效果与System.currentTimeMillis()相似,但提供了更高的精度和更好的API设计。

代码展示:

import java.time.Instant;

public class InstantExample {
    public static void main(String[] args) {
        // 创建Instant对象
        Instant instant = Instant.now();
        System.out.println("Current Instant: " + instant);

        // 获取纪元秒和纳秒部分
        long epochSecond = instant.getEpochSecond();
        int nano = instant.getNano();
        System.out.println("Epoch Second: " + epochSecond);
        System.out.println("Nano: " + nano);

        // 转换为时间戳
        long timestamp = instant.toEpochMilli();
        System.out.println("Timestamp: " + timestamp);

        // 从毫秒级时间戳构造Instant对象
        Instant fromTimestamp = Instant.ofEpochMilli(timestamp);
        System.out.println("Instant from Timestamp: " + fromTimestamp);
    }
}

上述代码演示了如何使用Instant类来创建、查询和转换时间点。首先,我们使用Instant.now()方法创建一个表示当前时间的Instant对象。然后,我们使用instant.getEpochSecond()instant.getNano()方法分别获取纪元秒和纳秒部分。接下来,我们使用instant.toEpochMilli()方法将Instant对象转换为毫秒级别的时间戳。最后,我们使用Instant.ofEpochMilli()方法从一个已知的毫秒级时间戳构造出一个Instant对象。

ZoneDateTime类

Java中的ZonedDateTime类是一个用于表示日期和时间的类,它包括时区信息

以下是一些关于ZonedDateTime类的关键点:

  • 包含时区信息:与LocalDateTime不同,ZonedDateTime包含了时区信息,这使得它能够精确地表示世界各地不同时间点的时间。
  • 创建方法:可以通过ZonedDateTime.now()获取当前的日期和时间,或者使用ZonedDateTime.of(LocalDateTime, ZoneId)来组合本地日期时间和特定的时区。还可以使用Clock.systemUTC()Clock.systemDefault()来指定一个时钟,从而获取标准时区或特定时区的当前时间。
  • 与其他类配合使用ZonedDateTime可以与InstantLocalDateTimeZoneId等类结合使用,以进行时间点的转换和计算。
  • 夏令时处理ZonedDateTime会自动处理夏令时的变化,确保时间的准确性。
  • 避免身份敏感操作:在ZonedDateTime实例上应避免使用身份敏感操作(如引用相等性检查),因为这可能会产生不可预测的结果。应该使用equals方法来比较两个ZonedDateTime对象是否相等。

 代码展示:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class ZonedDateTimeExample {
    public static void main(String[] args) {
        // 创建ZonedDateTime对象
        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        System.out.println("Current date and time: " + zonedDateTime);

        // 获取时区信息
        ZoneId zoneId = zonedDateTime.getZone();
        System.out.println("Timezone: " + zoneId);

        // 将ZonedDateTime转换为LocalDateTime
        LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
        System.out.println("Local date and time: " + localDateTime);

        // 将LocalDateTime与特定的ZoneId结合,得到一个ZonedDateTime对象
        ZonedDateTime newZonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
        System.out.println("New ZonedDateTime: " + newZonedDateTime);

        // 使用Clock类获取当前时间
        Clock clock = Clock.systemUTC();
        ZonedDateTime clockZonedDateTime = ZonedDateTime.now(clock);
        System.out.println("Clock ZonedDateTime: " + clockZonedDateTime);
    }
}

上述代码演示了如何使用ZonedDateTime类来创建、查询和转换日期和时间。首先,我们使用ZonedDateTime.now()方法创建一个表示当前时间的ZonedDateTime对象。然后,我们使用zonedDateTime.getZone()方法获取时区信息。接下来,我们将ZonedDateTime对象转换为LocalDateTime对象,并使用ZonedDateTime.of()方法将其与特定的时区结合,得到一个新的ZonedDateTime对象。最后,我们使用Clock类获取当前时间,并将其转换为ZonedDateTime对象。

DateTimeFormatter类

Java中的DateTimeFormatter类用于格式化和解析日期时间对象,它是处理日期时间格式化的强大而灵活的工具

DateTimeFormatter类在Java中扮演着至关重要的角色,它允许开发者对日期和时间进行定制输出,以适应不同的语言环境和格式要求。以下是DateTimeFormatter类的一些关键信息:

  • 格式化和解析功能:DateTimeFormatter类提供了将日期时间对象转换为字符串的方法,同时也支持将字符串解析为日期时间对象。
  • 模式字符串:通过使用模式字符串,开发者可以定义日期时间的格式。这些模式字符串的使用方式与SimpleDateFormat类似,例如"yyyy-MM-dd HH:mm"表示年-月-日 时:分的格式。
  • 本地化支持:DateTimeFormatter支持本地化,这意味着可以根据指定的语言环境来格式化日期时间,使得输出符合当地的习惯和规则。
  • 预定义的格式化器:DateTimeFormatter类提供了一些预定义的格式化器,如ISO_LOCAL_DATE_TIME,这些格式化器可以直接用于常见的日期时间格式。
  • 线程安全:DateTimeFormatter是不变的,因此是不可变的,可以安全地在多线程环境中使用。

 代码展示:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateTimeFormatterExample {
    public static void main(String[] args) {
        // 创建DateTimeFormatter对象
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println("Formatted date and time: " + formatter.format(LocalDateTime.now()));

        // 解析日期时间字符串
        String dateTimeStr = "2022-12-31 23:59";
        LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeStr, formatter);
        System.out.println("Parsed date and time: " + parsedDateTime);

        // 使用预定义的格式化器
        DateTimeFormatter predefinedFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        System.out.println("Predefined formatter: " + predefinedFormatter.format(LocalDateTime.now()));
    }
}

上述代码演示了如何使用DateTimeFormatter类来格式化和解析日期时间。首先,我们使用DateTimeFormatter.ofPattern()方法创建一个自定义的格式化器,并使用它来格式化当前日期和时间。然后,我们使用LocalDateTime.parse()方法将一个日期时间字符串解析为一个LocalDateTime对象。最后,我们展示了如何使用预定义的格式化器来格式化日期时间。

LocalDate类

Java中的LocalDate类是一个用于表示日期的类,它不包含时间和时区信息

以下是一些关于LocalDate类的关键点:

  • 不包含时间和时区LocalDate类只关注日期部分,即年、月、日,格式为yyyy-MM-dd,不包括时间或时区信息。
  • 不可变性和线程安全LocalDate对象一旦创建,其内容不可更改,这使得它成为一个不可变类。同时,由于其不可变性,LocalDate也是线程安全的。
  • API功能LocalDate类提供了丰富的方法来处理日期,如获取当前日期、解析日期字符串、进行日期计算等。例如,使用LocalDate.now()可以获取当前日期,而DateTimeFormatter.ISO_DATE.format(localDate)可以将LocalDate对象格式化为字符串。
  • 比较日期:由于LocalDate是一个基于值的类,要比较两个LocalDate实例是否相等,应该使用它的equals方法而不是引用相等性检查。
  • 适用场景LocalDate适用于需要表示纯日期的场景,如生日、纪念日、节假日等,不适合需要精确到时间的场景。

代码展示:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

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

        // 解析日期字符串
        String dateStr = "2022-12-31";
        LocalDate parsedDate = LocalDate.parse(dateStr);
        System.out.println("Parsed date: " + parsedDate);

        // 格式化日期对象为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        String formattedDate = currentDate.format(formatter);
        System.out.println("Formatted date: " + formattedDate);

        // 比较两个日期对象是否相等
        LocalDate anotherDate = LocalDate.of(2022, 12, 31);
        boolean isEqual = currentDate.equals(anotherDate);
        System.out.println("Is equal: " + isEqual);
    }
}

 上述代码演示了如何使用LocalDate类来处理日期。首先,我们使用LocalDate.now()方法获取当前日期。然后,我们使用LocalDate.parse()方法将一个日期字符串解析为一个LocalDate对象。接下来,我们使用DateTimeFormatter类将LocalDate对象格式化为字符串。最后,我们使用equals()方法比较两个LocalDate对象是否相等。

LocalTime类

Java中的LocalTime类是一个用于表示时间的类,它不包含日期和时区信息

以下是一些关于LocalTime类的关键点:

  • 不包含日期和时区LocalTime类只关注时间部分,即小时、分钟、秒和纳秒,格式为HH:mm:ss.SSSSSS,不包括日期或时区信息。
  • 不可变性和线程安全:与LocalDate类似,LocalTime对象一旦创建,其内容不可更改,这使得它成为一个不可变类。同时,由于其不可变性,LocalTime也是线程安全的。
  • API功能LocalTime类提供了丰富的方法来处理时间,如获取当前时间、解析时间字符串、进行时间计算等。例如,使用LocalTime.now()可以获取当前时间,而DateTimeFormatter.ISO_TIME.format(localTime)可以将LocalTime对象格式化为字符串。
  • 比较时间:由于LocalTime是一个基于值的类,要比较两个LocalTime实例是否相等,应该使用它的equals方法而不是引用相等性检查。
  • 适用场景LocalTime适用于需要表示纯时间的场景,如工作时间、会议时间等,不适合需要精确到日期的场景。

代码展示:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

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

        // 解析时间字符串
        String timeStr = "12:34:56";
        LocalTime parsedTime = LocalTime.parse(timeStr);
        System.out.println("Parsed time: " + parsedTime);

        // 格式化时间对象为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        String formattedTime = currentTime.format(formatter);
        System.out.println("Formatted time: " + formattedTime);

        // 比较两个时间对象是否相等
        LocalTime anotherTime = LocalTime.of(12, 34, 56);
        boolean isEqual = currentTime.equals(anotherTime);
        System.out.println("Is equal: " + isEqual);
    }
}

上述代码演示了如何使用LocalTime类来处理时间。首先,我们使用LocalTime.now()方法获取当前时间。然后,我们使用LocalTime.parse()方法将一个时间字符串解析为一个LocalTime对象。接下来,我们使用DateTimeFormatter类将LocalTime对象格式化为字符串。最后,我们使用equals()方法比较两个LocalTime对象是否相等。

LocalDateTime类

Java中的LocalDateTime类是一个用于表示日期和时间的类,它不包含时区信息

以下是一些关于LocalDateTime类的关键点:

  • 结合了日期和时间:与LocalDateLocalTime不同,LocalDateTime同时包含了日期和时间信息,格式为yyyy-MM-dd HH:mm:ss。
  • 不可变性和线程安全LocalDateTime对象一旦创建,其内容不可更改,这使得它成为一个不可变类。同时,由于其不可变性,LocalDateTime也是线程安全的。
  • API功能LocalDateTime类提供了丰富的方法来处理日期和时间,如获取当前日期和时间、解析日期时间字符串、进行日期时间计算等。例如,使用LocalDateTime.now()可以获取当前日期和时间,而DateTimeFormatter.ISO_DATE_TIME.format(localDateTime)可以将LocalDateTime对象格式化为字符串。
  • 比较日期时间:由于LocalDateTime是一个基于值的类,要比较两个LocalDateTime实例是否相等,应该使用它的equals方法而不是引用相等性检查。
  • 适用场景LocalDateTime适用于需要表示具体日期和时间的场景,如日程安排、预订系统等,不适合需要精确到时区的场景。

 代码展示:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

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

        // 解析日期时间字符串
        String dateTimeStr = "2022-12-31T12:34:56";
        LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeStr);
        System.out.println("Parsed date and time: " + parsedDateTime);

        // 格式化日期时间对象为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        String formattedDateTime = currentDateTime.format(formatter);
        System.out.println("Formatted date and time: " + formattedDateTime);

        // 比较两个日期时间对象是否相等
        LocalDateTime anotherDateTime = LocalDateTime.of(2022, 12, 31, 12, 34, 56);
        boolean isEqual = currentDateTime.equals(anotherDateTime);
        System.out.println("Is equal: " + isEqual);
    }
}

上述代码演示了如何使用LocalDateTime类来处理日期和时间。首先,我们使用LocalDateTime.now()方法获取当前日期和时间。然后,我们使用LocalDateTime.parse()方法将一个日期时间字符串解析为一个LocalDateTime对象。接下来,我们使用DateTimeFormatter类将LocalDateTime对象格式化为字符串。最后,我们使用equals()方法比较两个LocalDateTime对象是否相等。

Duration类

Java中的Duration类用于表示一段时间量,它可以精确到纳秒级别

以下是一些关于Duration类的关键点:

  • 时间单位的精度Duration类可以表示的时间单位包括年、月、日、小时、分钟、秒和纳秒,它的最高精度是纳秒。
  • 可正可负:这个类可以表示正的或负的时间量,例如1天可以是86400秒0纳秒,而-1天则是-86400秒0纳秒。
  • 不可变性与线程安全Duration对象一旦创建,其内容不可更改,这使它成为一个不可变类。同时,由于其不可变性,Duration类也是线程安全的。
  • 与Period类的区别Duration类与Period类都是JDK 8新增的,用于表示时间段。不同之处在于Duration基于时间值(如天数、小时数),而Period基于日期值(如年数、月数)。
  • 创建方法:可以通过Duration.ofHours(long)Duration.ofMinutes(long)Duration.ofSeconds(long)等静态方法来创建Duration对象。也可以通过两个Instant对象之间的差值来创建Duration对象,例如Duration.between(Instant start, Instant end)

 代码展示:

import java.time.Duration;
import java.time.Instant;

public class DurationExample {
    public static void main(String[] args) {
        // 创建Duration对象
        Duration duration1 = Duration.ofHours(2); // 2小时
        Duration duration2 = Duration.ofMinutes(30); // 30分钟
        Duration duration3 = Duration.ofSeconds(45); // 45秒
        Duration duration4 = Duration.ofNanos(123456789); // 123456789纳秒

        // 获取时间单位
        long hours = duration1.toHours(); // 2小时
        long minutes = duration2.toMinutes(); // 30分钟
        long seconds = duration3.getSeconds(); // 45秒
        long nanos = duration4.toNanos(); // 123456789纳秒

        // 计算时间间隔
        Instant start = Instant.now();
        // do something...
        Instant end = Instant.now();
        Duration duration5 = Duration.between(start, end); // 两个Instant之间的时间间隔

        // 比较时间间隔
        boolean isEqual = duration1.equals(duration2); // false
        boolean isGreaterThan = duration1.compareTo(duration2) > 0; // true
        boolean isLessThanOrEqualTo = duration1.minus(duration2).isNegative() || duration1.minus(duration2).isZero(); // true

        // 输出结果
        System.out.println("hours: " + hours);
        System.out.println("minutes: " + minutes);
        System.out.println("seconds: " + seconds);
        System.out.println("nanos: " + nanos);
        System.out.println("duration5: " + duration5);
        System.out.println("isEqual: " + isEqual);
        System.out.println("isGreaterThan: " + isGreaterThan);
        System.out.println("isLessThanOrEqualTo: " + isLessThanOrEqualTo);
    }
}

上述代码演示了如何使用Duration类来创建和操作时间段。我们使用Duration.ofHours()Duration.ofMinutes()Duration.ofSeconds()Duration.ofNanos()方法来创建不同的Duration对象,并使用toHours()toMinutes()getSeconds()toNanos()方法来获取时间单位。我们还使用Duration.between()方法来计算两个Instant对象之间的时间间隔,并使用equals()compareTo()minus()方法来比较时间间隔。最后,我们将结果打印到控制台上。

Period类

Java中的Period类是用来表示日期间隔的,它可以精确到年、月和日

以下是一些关于Period类的关键点:

  • 计算日期间隔Period类主要用于计算两个LocalDate对象之间的时间间隔。它提供的方法包括getYears()getMonths()getDays(),这些方法分别用于获取间隔的年数、月数和天数。
  • 使用流程:首先需要导入java.time.Period类。然后创建两个LocalDate对象,表示需要比较的两个日期。接着使用Period.between(date1, date2)方法来计算这两个日期之间的间隔。最后,可以调用Period对象的getYears()getMonths()getDays()方法来获取具体的年、月、日数值。
  • 应用场景Period类适用于需要计算日期间隔的场景,比如计算两个日期之间相差的具体年数、月数和天数。它不涉及时间的具体小时和分钟,因此不适合用于需要精确到更小时间单位的情况。
  • 不可变性和线程安全:与LocalDate类似,Period对象一旦创建,其内容不可更改,这使得它成为不可变类。同时,由于其不可变性,Period类也是线程安全的。

 代码展示:

import java.time.LocalDate;
import java.time.Period;

public class PeriodExample {
    public static void main(String[] args) {
        // 创建两个LocalDate对象
        LocalDate date1 = LocalDate.of(2022, 1, 1);
        LocalDate date2 = LocalDate.of(2023, 6, 30);

        // 计算日期间隔
        Period period = Period.between(date1, date2);

        // 获取年、月、日数值
        int years = period.getYears(); // 1年
        int months = period.getMonths(); // 5个月
        int days = period.getDays(); // 29天

        // 输出结果
        System.out.println("years: " + years);
        System.out.println("months: " + months);
        System.out.println("days: " + days);
    }
}

上述代码演示了如何使用Period类来计算两个LocalDate对象之间的时间间隔。我们首先创建了两个LocalDate对象,表示需要比较的两个日期。然后使用Period.between(date1, date2)方法来计算这两个日期之间的间隔。最后,我们可以调用Period对象的getYears()getMonths()getDays()方法来获取具体的年、月、日数值,并将它们打印到控制台上。

ChronoUnit类

ChronoUnit是Java 8中提供的一个枚举类,它定义了一组标准的日期时间单位,用于基于单元的访问来操纵日期、时间或日期时间

ChronoUnit类位于java.time.temporal包中,它实现了TemporalUnit接口,从而提供了一组标准的日期时间单位。这些单位适用于多个日历系统,例如大多数非ISO日历系统定义了年、月和日的单位,但可能有不同的规则。每个单元的文档都说明了它的运作方式。

ChronoUnit类提供了以下枚举常量:

  • CENTURIES:代表一个世纪概念的单位。
  • DAYS:代表一天概念的单位。
  • DECADES:代表十年概念的单位。
  • ERAS:代表一个时代概念的单位。
  • FOREVER:代表永恒概念的人工单位。
  • HALF_DAYS:代表AM/PM中使用的半天概念的单位。
  • HOURS:表示一小时概念的单位。
  • MICROS:表示微秒概念的单位。
  • MILLENNIA:代表千年概念的单位。
  • MILLIS:表示毫秒概念的单位。
  • MINUTES:表示一分钟概念的单位。
  • MONTHS:代表一个月概念的单位。
  • NANOS:代表纳秒概念的单位,是支持的最小时间单位。
  • SECONDS:表示第二个概念的单位。
  • WEEKS:表示一周概念的单位。
  • YEARS:代表一年概念的单位。

此外,ChronoUnit类还实现了SerializableComparable<ChronoUnit>接口,确保了其实例可以序列化并且可以相互比较。这个枚举是不可变的,因此它是线程安全的。从Java 8开始引入,ChronoUnit与Duration和Period一起,成为处理时间相关计算的重要工具。

 代码展示:

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class ChronoUnitExample {
    public static void main(String[] args) {
        // 创建两个LocalDate对象
        LocalDate date1 = LocalDate.of(2022, 1, 1);
        LocalDate date2 = LocalDate.of(2023, 6, 30);

        // 计算日期间隔
        long days = ChronoUnit.DAYS.between(date1, date2); // 594天
        long months = ChronoUnit.MONTHS.between(date1, date2); // 23个月
        long years = ChronoUnit.YEARS.between(date1, date2); // 1年

        // 输出结果
        System.out.println("days: " + days);
        System.out.println("months: " + months);
        System.out.println("years: " + years);
    }
}

上述代码演示了如何使用ChronoUnit类来计算两个LocalDate对象之间的时间间隔。我们首先创建了两个LocalDate对象,表示需要比较的两个日期。然后使用ChronoUnit.DAYS.between(date1, date2)ChronoUnit.MONTHS.between(date1, date2)ChronoUnit.YEARS.between(date1, date2)方法来计算这两个日期之间的间隔。最后,我们可以将结果打印到控制台上。

  • 26
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值