java8日期时间工具类

【README】

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

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

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

java 复制代码
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】当前日期时间操作

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

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

【1.1】单测案例:

java 复制代码
/** -------------------- 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】字符串解析为日期时间对象

java 复制代码
 /** -------------------- 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】单测案例

java 复制代码
/** -------------------- 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】日期时间对象格式化为字符串

java 复制代码
/** -------------------- 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】单测案例

java 复制代码
/** -------------------- 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 转为其他日期时间类型(重要)

java 复制代码
/** -------------------- 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】单测案例

java 复制代码
/** -------------------- 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 转为其他日期时间类型

java 复制代码
/** -------------------- 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】单测案例

java 复制代码
/** -------------------- 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 转为其他日期时间类型

java 复制代码
/** -------------------- 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】单测案例

java 复制代码
/** -------------------- 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 剖析

java 复制代码
/** -------------------- 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】日期时间工具类

java 复制代码
/**
 * @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】日期时间工具类单测案例

java 复制代码
/**
 * @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
    }
}
相关推荐
苹果醋329 分钟前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
晓纪同学1 小时前
QT-简单视觉框架代码
开发语言·qt
威桑1 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
Hello.Reader1 小时前
深入解析 Apache APISIX
java·apache
飞飞-躺着更舒服1 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生1 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生1 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans1 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手1 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
菠萝蚊鸭1 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel