java8日期时间工具类

【README】

1)本文总结了java8中日期时间常用工具方法;包括:

  • 日期时间对象格式化为字符串;
  • 日期时间字符串解析为日期时间对象;
  • 日期时间对象转换;
    • 转换过程中,需要注意的是: Instant与Date带时区(易变),而LocalDateTime,LocalDate,LocalTime 不带时区(不可变)
  • 带时区的日期时间 ZonedDateTime 剖析;

2)日期时间工具类定义如下:

public class BusiDateTimeUtils {

    /** 日期时间格式化器 */
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /** 日期格式化器 */
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private BusiDateTimeUtils() {
        // do nothing.
    }
// .................... 
}


【1】当前日期时间操作

/** -------------------- 1. 当前日期时间操作 -------------------- */
    public static String getNowLocalDateTimeStr() {
        return LocalDateTime.now().format(DATETIME_FORMATTER);
    }

    public static String getNowLocalDateStr() {
        return LocalDate.now().format(DATE_FORMATTER);
    }

【1.1】单测案例:

/** -------------------- 1. 当前日期时间操作 -------------------- */
    @Test
    public void test1() {
        // 获取当前日期时间
        String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
        System.out.println("nowLocalDateTimeStr="+nowLocalDateTimeStr); // 2023-10-05 21:28:09

        // 获取当前日期
        String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
        System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    }

【2】字符串解析为日期时间对象

 /** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    public static LocalDateTime parseLocalDateTime(String dateTimeStr) {
        return LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
    }

    public static LocalDate parseLocalDate(String dateStr) {
        return LocalDate.parse(dateStr, DATE_FORMATTER);
    }

【2.1】单测案例

/** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    @Test
    public void test2() {
        // 解析当前日期时间
        String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
        System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:29:32
        LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
        System.out.println(parsedLocalDateTime); // 2023-10-05T21:29:32

        // 解析当前日期
        String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
        System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
        LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
        System.out.println(parsedLocalDate); // 2023-10-05
    }

【3】日期时间对象格式化为字符串

/** -------------------- 3. 日期时间对象格式化为字符串 -------------------- */
    public static String format(LocalDateTime localDateTime) {
        return localDateTime.format(DATETIME_FORMATTER);
    }
    public static String format(LocalDate localDate) {
        return localDate.format(DATE_FORMATTER);
    }

【3.1】单测案例

/** -------------------- 3. 日期时间对象格式化为字符串 -------------------- */
    @Test
    public void test3() {
        // 格式化当前日期时间对象为字符串
        String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
        System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:35:19

        LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
        String formatedLocalDateTime = BusiDateTimeUtils.format(parsedLocalDateTime);
        System.out.println(formatedLocalDateTime); // 2023-10-05 21:35:19

        // 格式化当前日期对象为字符串
        String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
        System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05

        LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
        String formatedLocalDate = BusiDateTimeUtils.format(parsedLocalDate);
        System.out.println(formatedLocalDate); // 2023-10-05
    }

【4】*LocalDateTime 转为其他日期时间类型(重要)

/** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    public static LocalDate toLocalDate(LocalDateTime localDateTime) {
        return localDateTime.toLocalDate();
    }

    public static Instant toInstant(LocalDateTime localDateTime) {
        return localDateTime.toInstant(ZoneOffset.UTC);
    }

    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

【说明】LocalDateTime 转 Instant与Date时,做了一些特殊处理:

  • LocalDateTime没有时区,而Instant有时区;为了统一,把Instant的时区设置为0时区(UTC),则LocalDateTime与Instant都没有时区了;
  • LocalDateTime没有时区,Instant有时区,Date有时区:
    • 先把 LocalDateTime转为带时区的日期时间 ZonedDateTime
    • 再把 ZonedDateTime 转 Instant(默认时区为系统时区);
    • 最后把Instant转Date(默认时区为系统时区); 

【4.1】单测案例

/** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    @Test
    public void test4() {
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        System.out.println("nowLocalDateTimeStr="+BusiDateTimeUtils.format(nowLocalDateTime)); // 2023-10-05 21:37:14

        // LocalDateTime 转 LocalDate
        LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowLocalDateTime);
        LocalDate localDate2 = nowLocalDateTime.toLocalDate(); // 与上一行代码效果一样
        System.out.println("localDate=" + localDate); // 2023-10-05

        // LocalDateTime 转 Instant
        Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDateTime);
        System.out.println(nowInstant); // 2023-10-05T21:37:14.677Z

        // LocalDateTime 转 Date
        Date nowDate = BusiDateTimeUtils.toDate(nowLocalDateTime);
        System.out.println(nowDate); // Thu Oct 05 21:37:14 CST 2023 
    }

【5】LocalDate 转为其他日期时间类型

/** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    public static LocalDateTime toLocalDateTime(LocalDate localDate) {
        return localDate.atStartOfDay();
    }

    public static Instant toInstant(LocalDate localDate) {
        return localDate.atStartOfDay().toInstant(ZoneOffset.UTC);
    }

    public static Date toDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

【说明】LocalDate 转 Instant与Date时,做了一些特殊处理:与 LocalDateTime 转 Instant与Date类似 ,这里不再赘述;参见本文章节【4】;

【5.1】单测案例

/** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    @Test
    public void test5() {
        LocalDate nowLocalDate = LocalDate.now();
        System.out.println("nowLocalDateStr="+BusiDateTimeUtils.format(nowLocalDate)); // 2023-10-05

        // LocalDate 转 LocalDateTime
        LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowLocalDate);
        System.out.println("localDateTime=" + localDateTime); // 2023-10-05T00:00

        // LocalDate 转 Instant
        Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDate);
        System.out.println(nowInstant); // 2023-10-05T00:00

        // LocalDate 转 Date
        Date nowDate = BusiDateTimeUtils.toDate(nowLocalDate);
        System.out.println(nowDate); //  Thu Oct 05 00:00:00 CST 2023
    }

【6】Instant 转为其他日期时间类型

/** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    public static LocalDateTime toLocalDateTime(Instant instantWithoutZone) {
        return LocalDateTime.ofInstant(instantWithoutZone, ZoneOffset.UTC);
    }

    public static LocalDate toLocalDate(Instant instantWithoutZone) {
        return toLocalDateTime(instantWithoutZone).toLocalDate();
    }

    public static Date toDate(Instant instantWithoutZone) {
        return toDate(toLocalDateTime(instantWithoutZone));
    }

【说明】

注意上述工具方法中入参 Instant变量是不带时区的,也可以理解为时区为UTC(0时区)

【6.1】单测案例

/** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    @Test
    public void test6() {
        Instant nowInstantWithoutZone = LocalDateTime.now().toInstant(ZoneOffset.UTC);
        System.out.println("nowZonedInstant="+nowInstantWithoutZone); // 2023-10-05T22:00:54.783Z
        System.out.println("Instant.now()=" + Instant.now()); // 2023-10-05T14:00:54.798Z(注意这里晚了8个小时)

        // Instant 转 LocalDateTime
        LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowInstantWithoutZone);
        System.out.println("localDateTime=" + localDateTime); // 2023-10-05T22:00:54.783

        // Instant 转 LocalDate
        LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowInstantWithoutZone);
        System.out.println("localDate=" + localDate); // 2023-10-05

        // Instant 转 Date
        Date date = BusiDateTimeUtils.toDate(nowInstantWithoutZone);
        System.out.println("date=" + date); // date=Thu Oct 05 22:00:54 CST 2023 
    }

【7】总结

【7.1】带时区的日期时间 ZonedDateTime 剖析

/** -------------------- 7. 带时区的日期时间 -------------------- */
    @Test
    public void test7() {
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        System.out.println("nowLocalDateTime=" + nowLocalDateTime); // 2023-10-05T22:19:10.812 

        // 转为带时区的日期时间(系统时区)
        System.out.println("ZoneId.systemDefault()=" + ZoneId.systemDefault()); // Asia/Shanghai
        ZonedDateTime zonedDateTime = nowLocalDateTime.atZone(ZoneId.systemDefault());
        System.out.println("zonedDateTime.toInstant()(系统时区)="+zonedDateTime.toInstant()); // 2023-10-05T14:19:10.812Z(晚8个小时)

        // 转为带时区的日期时间(0时区)
        zonedDateTime = nowLocalDateTime.atZone(ZoneOffset.UTC);
        System.out.println("zonedDateTime.toInstant()(0时区)="+zonedDateTime.toInstant()); // 2023-10-05T22:19:10.812Z
    }

【说明】

  • 1)系统时区解析后的Instant,晚8个小时;
    • 原因: LocalDateTime 本身没有时区,根据系统时区(东8区)把LocalDateTime 转为  ZonedDateTime后,把ZonedDateTime转为Instant时,jdk认为 LocalDateTime 的时区为东8区的时间,转Instant默认使用0时区;因为东8区比0时区快8个小时,所以减去了8个小时
  • 2)0时区解析后的Instant,转换正确;
    • 原因:LocalDateTime 本身没有时区,根据0时区把LocalDateTime 转为  ZonedDateTime后,把ZonedDateTime转为Instant时,jdk认为 LocalDateTime 的时区为0时区的时间,转Instant默认使用0时区,两者使用的时区一致,所以转换正确

【7.2】日期时间工具类

/**
 * @Description 日期时间工具类
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2023年10月05日
 */
public class BusiDateTimeUtils {

    /** 日期时间格式化器 */
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /** 日期格式化器 */
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private BusiDateTimeUtils() {
        // do nothing.
    }

    /** -------------------- 1. 当前日期时间操作 -------------------- */
    public static String getNowLocalDateTimeStr() {
        return LocalDateTime.now().format(DATETIME_FORMATTER);
    }

    public static String getNowLocalDateStr() {
        return LocalDate.now().format(DATE_FORMATTER);
    }

    /** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    public static LocalDateTime parseLocalDateTime(String dateTimeStr) {
        return LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
    }

    public static LocalDate parseLocalDate(String dateStr) {
        return LocalDate.parse(dateStr, DATE_FORMATTER);
    }

    /** -------------------- 3. 日期时间对象格式化为字符串 -------------------- */
    public static String format(LocalDateTime localDateTime) {
        return localDateTime.format(DATETIME_FORMATTER);
    }
    public static String format(LocalDate localDate) {
        return localDate.format(DATE_FORMATTER);
    }

    /** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    public static LocalDate toLocalDate(LocalDateTime localDateTime) {
        return localDateTime.toLocalDate();
    }

    public static Instant toInstant(LocalDateTime localDateTime) {
        return localDateTime.toInstant(ZoneOffset.UTC);
    }

    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    public static LocalDateTime toLocalDateTime(LocalDate localDate) {
        return localDate.atStartOfDay();
    }

    public static Instant toInstant(LocalDate localDate) {
        return localDate.atStartOfDay().toInstant(ZoneOffset.UTC);
    }

    public static Date toDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    /** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    public static LocalDateTime toLocalDateTime(Instant instantWithoutZone) {
        return LocalDateTime.ofInstant(instantWithoutZone, ZoneOffset.UTC);
    }

    public static LocalDate toLocalDate(Instant instantWithoutZone) {
        return toLocalDateTime(instantWithoutZone).toLocalDate();
    }

    public static Date toDate(Instant instantWithoutZone) {
        return toDate(toLocalDateTime(instantWithoutZone));
    }
}

【7.3】日期时间工具类单测案例

/**
 * @Description 日期时间工具类单测案例 
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2023年10月05日
 */
public class BusiDateTimeUtilsTest {

    /** -------------------- 1. 当前日期时间操作 -------------------- */
    @Test
    public void test1() {
        // 获取当前日期时间
        String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
        System.out.println("nowLocalDateTimeStr="+nowLocalDateTimeStr); // 2023-10-05 21:28:09

        // 获取当前日期
        String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
        System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    }

    /** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    @Test
    public void test2() {
        // 解析当前日期时间
        String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
        System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:29:32
        LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
        System.out.println(parsedLocalDateTime); // 2023-10-05T21:29:32

        // 解析当前日期
        String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
        System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
        LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
        System.out.println(parsedLocalDate); // 2023-10-05
    }

    /** -------------------- 3. 日期时间对象格式化为字符串 -------------------- */
    @Test
    public void test3() {
        // 格式化当前日期时间对象为字符串
        String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
        System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:35:19

        LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
        String formatedLocalDateTime = BusiDateTimeUtils.format(parsedLocalDateTime);
        System.out.println(formatedLocalDateTime); // 2023-10-05 21:35:19

        // 格式化当前日期对象为字符串
        String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
        System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05

        LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
        String formatedLocalDate = BusiDateTimeUtils.format(parsedLocalDate);
        System.out.println(formatedLocalDate); // 2023-10-05
    }

    /** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    @Test
    public void test4() {
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        System.out.println("nowLocalDateTimeStr="+BusiDateTimeUtils.format(nowLocalDateTime)); // 2023-10-05 21:37:14

        // LocalDateTime 转 LocalDate
        LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowLocalDateTime);
        LocalDate localDate2 = nowLocalDateTime.toLocalDate(); // 与上一行代码效果一样
        System.out.println("localDate=" + localDate); // 2023-10-05

        // LocalDateTime 转 Instant
        Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDateTime);
        System.out.println(nowInstant); // 2023-10-05T21:37:14.677Z

        // LocalDateTime 转 Date
        Date nowDate = BusiDateTimeUtils.toDate(nowLocalDateTime);
        System.out.println(nowDate); // Thu Oct 05 21:37:14 CST 2023
    }

    /** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    @Test
    public void test5() {
        LocalDate nowLocalDate = LocalDate.now();
        System.out.println("nowLocalDateStr="+BusiDateTimeUtils.format(nowLocalDate)); // 2023-10-05

        // LocalDate 转 LocalDateTime
        LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowLocalDate);
        System.out.println("localDateTime=" + localDateTime); // 2023-10-05T00:00

        // LocalDate 转 Instant
        Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDate);
        System.out.println(nowInstant); // 2023-10-05T00:00

        // LocalDate 转 Date
        Date nowDate = BusiDateTimeUtils.toDate(nowLocalDate);
        System.out.println(nowDate); //  Thu Oct 05 00:00:00 CST 2023
    }

    /** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    @Test
    public void test6() {
        Instant nowInstantWithoutZone = LocalDateTime.now().toInstant(ZoneOffset.UTC);
        System.out.println("nowZonedInstant="+nowInstantWithoutZone); // 2023-10-05T22:00:54.783Z
        System.out.println("Instant.now()=" + Instant.now()); // 2023-10-05T14:00:54.798Z(注意这里晚了8个小时)

        // Instant 转 LocalDateTime
        LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowInstantWithoutZone);
        System.out.println("localDateTime=" + localDateTime); // 2023-10-05T22:00:54.783

        // Instant 转 LocalDate
        LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowInstantWithoutZone);
        System.out.println("localDate=" + localDate); // 2023-10-05

        // Instant 转 Date
        Date date = BusiDateTimeUtils.toDate(nowInstantWithoutZone);
        System.out.println("date=" + date); // date=Thu Oct 05 22:00:54 CST 2023
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值