• java8日期时间工具类


    【README】

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

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

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

    1. public class BusiDateTimeUtils {
    2. /** 日期时间格式化器 */
    3. private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    4. /** 日期格式化器 */
    5. private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    6. private BusiDateTimeUtils() {
    7. // do nothing.
    8. }
    9. // ....................
    10. }


    【1】当前日期时间操作

    1. /** -------------------- 1. 当前日期时间操作 -------------------- */
    2. public static String getNowLocalDateTimeStr() {
    3. return LocalDateTime.now().format(DATETIME_FORMATTER);
    4. }
    5. public static String getNowLocalDateStr() {
    6. return LocalDate.now().format(DATE_FORMATTER);
    7. }

    【1.1】单测案例:

    1. /** -------------------- 1. 当前日期时间操作 -------------------- */
    2. @Test
    3. public void test1() {
    4. // 获取当前日期时间
    5. String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
    6. System.out.println("nowLocalDateTimeStr="+nowLocalDateTimeStr); // 2023-10-05 21:28:09
    7. // 获取当前日期
    8. String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
    9. System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    10. }

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

    1. /** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    2. public static LocalDateTime parseLocalDateTime(String dateTimeStr) {
    3. return LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
    4. }
    5. public static LocalDate parseLocalDate(String dateStr) {
    6. return LocalDate.parse(dateStr, DATE_FORMATTER);
    7. }

    【2.1】单测案例

    1. /** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    2. @Test
    3. public void test2() {
    4. // 解析当前日期时间
    5. String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
    6. System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:29:32
    7. LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
    8. System.out.println(parsedLocalDateTime); // 2023-10-05T21:29:32
    9. // 解析当前日期
    10. String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
    11. System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    12. LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
    13. System.out.println(parsedLocalDate); // 2023-10-05
    14. }

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

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

    【3.1】单测案例

    1. /** -------------------- 3. 日期时间对象格式化为字符串 -------------------- */
    2. @Test
    3. public void test3() {
    4. // 格式化当前日期时间对象为字符串
    5. String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
    6. System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:35:19
    7. LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
    8. String formatedLocalDateTime = BusiDateTimeUtils.format(parsedLocalDateTime);
    9. System.out.println(formatedLocalDateTime); // 2023-10-05 21:35:19
    10. // 格式化当前日期对象为字符串
    11. String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
    12. System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    13. LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
    14. String formatedLocalDate = BusiDateTimeUtils.format(parsedLocalDate);
    15. System.out.println(formatedLocalDate); // 2023-10-05
    16. }

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

    1. /** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    2. public static LocalDate toLocalDate(LocalDateTime localDateTime) {
    3. return localDateTime.toLocalDate();
    4. }
    5. public static Instant toInstant(LocalDateTime localDateTime) {
    6. return localDateTime.toInstant(ZoneOffset.UTC);
    7. }
    8. public static Date toDate(LocalDateTime localDateTime) {
    9. return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    10. }

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

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

    【4.1】单测案例

    1. /** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    2. @Test
    3. public void test4() {
    4. LocalDateTime nowLocalDateTime = LocalDateTime.now();
    5. System.out.println("nowLocalDateTimeStr="+BusiDateTimeUtils.format(nowLocalDateTime)); // 2023-10-05 21:37:14
    6. // LocalDateTime 转 LocalDate
    7. LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowLocalDateTime);
    8. LocalDate localDate2 = nowLocalDateTime.toLocalDate(); // 与上一行代码效果一样
    9. System.out.println("localDate=" + localDate); // 2023-10-05
    10. // LocalDateTime 转 Instant
    11. Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDateTime);
    12. System.out.println(nowInstant); // 2023-10-05T21:37:14.677Z
    13. // LocalDateTime 转 Date
    14. Date nowDate = BusiDateTimeUtils.toDate(nowLocalDateTime);
    15. System.out.println(nowDate); // Thu Oct 05 21:37:14 CST 2023
    16. }

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

    1. /** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    2. public static LocalDateTime toLocalDateTime(LocalDate localDate) {
    3. return localDate.atStartOfDay();
    4. }
    5. public static Instant toInstant(LocalDate localDate) {
    6. return localDate.atStartOfDay().toInstant(ZoneOffset.UTC);
    7. }
    8. public static Date toDate(LocalDate localDate) {
    9. return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    10. }

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

    【5.1】单测案例

    1. /** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    2. @Test
    3. public void test5() {
    4. LocalDate nowLocalDate = LocalDate.now();
    5. System.out.println("nowLocalDateStr="+BusiDateTimeUtils.format(nowLocalDate)); // 2023-10-05
    6. // LocalDate 转 LocalDateTime
    7. LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowLocalDate);
    8. System.out.println("localDateTime=" + localDateTime); // 2023-10-05T00:00
    9. // LocalDate 转 Instant
    10. Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDate);
    11. System.out.println(nowInstant); // 2023-10-05T00:00
    12. // LocalDate 转 Date
    13. Date nowDate = BusiDateTimeUtils.toDate(nowLocalDate);
    14. System.out.println(nowDate); // Thu Oct 05 00:00:00 CST 2023
    15. }

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

    1. /** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    2. public static LocalDateTime toLocalDateTime(Instant instantWithoutZone) {
    3. return LocalDateTime.ofInstant(instantWithoutZone, ZoneOffset.UTC);
    4. }
    5. public static LocalDate toLocalDate(Instant instantWithoutZone) {
    6. return toLocalDateTime(instantWithoutZone).toLocalDate();
    7. }
    8. public static Date toDate(Instant instantWithoutZone) {
    9. return toDate(toLocalDateTime(instantWithoutZone));
    10. }

    【说明】

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

    【6.1】单测案例

    1. /** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    2. @Test
    3. public void test6() {
    4. Instant nowInstantWithoutZone = LocalDateTime.now().toInstant(ZoneOffset.UTC);
    5. System.out.println("nowZonedInstant="+nowInstantWithoutZone); // 2023-10-05T22:00:54.783Z
    6. System.out.println("Instant.now()=" + Instant.now()); // 2023-10-05T14:00:54.798Z(注意这里晚了8个小时)
    7. // Instant 转 LocalDateTime
    8. LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowInstantWithoutZone);
    9. System.out.println("localDateTime=" + localDateTime); // 2023-10-05T22:00:54.783
    10. // Instant 转 LocalDate
    11. LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowInstantWithoutZone);
    12. System.out.println("localDate=" + localDate); // 2023-10-05
    13. // Instant 转 Date
    14. Date date = BusiDateTimeUtils.toDate(nowInstantWithoutZone);
    15. System.out.println("date=" + date); // date=Thu Oct 05 22:00:54 CST 2023
    16. }

    【7】总结

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

    1. /** -------------------- 7. 带时区的日期时间 -------------------- */
    2. @Test
    3. public void test7() {
    4. LocalDateTime nowLocalDateTime = LocalDateTime.now();
    5. System.out.println("nowLocalDateTime=" + nowLocalDateTime); // 2023-10-05T22:19:10.812
    6. // 转为带时区的日期时间(系统时区)
    7. System.out.println("ZoneId.systemDefault()=" + ZoneId.systemDefault()); // Asia/Shanghai
    8. ZonedDateTime zonedDateTime = nowLocalDateTime.atZone(ZoneId.systemDefault());
    9. System.out.println("zonedDateTime.toInstant()(系统时区)="+zonedDateTime.toInstant()); // 2023-10-05T14:19:10.812Z(晚8个小时)
    10. // 转为带时区的日期时间(0时区)
    11. zonedDateTime = nowLocalDateTime.atZone(ZoneOffset.UTC);
    12. System.out.println("zonedDateTime.toInstant()(0时区)="+zonedDateTime.toInstant()); // 2023-10-05T22:19:10.812Z
    13. }

    【说明】

    • 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】日期时间工具类

    1. /**
    2. * @Description 日期时间工具类
    3. * @author xiao tang
    4. * @version 1.0.0
    5. * @createTime 2023年10月05日
    6. */
    7. public class BusiDateTimeUtils {
    8. /** 日期时间格式化器 */
    9. private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    10. /** 日期格式化器 */
    11. private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    12. private BusiDateTimeUtils() {
    13. // do nothing.
    14. }
    15. /** -------------------- 1. 当前日期时间操作 -------------------- */
    16. public static String getNowLocalDateTimeStr() {
    17. return LocalDateTime.now().format(DATETIME_FORMATTER);
    18. }
    19. public static String getNowLocalDateStr() {
    20. return LocalDate.now().format(DATE_FORMATTER);
    21. }
    22. /** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    23. public static LocalDateTime parseLocalDateTime(String dateTimeStr) {
    24. return LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
    25. }
    26. public static LocalDate parseLocalDate(String dateStr) {
    27. return LocalDate.parse(dateStr, DATE_FORMATTER);
    28. }
    29. /** -------------------- 3. 日期时间对象格式化为字符串 -------------------- */
    30. public static String format(LocalDateTime localDateTime) {
    31. return localDateTime.format(DATETIME_FORMATTER);
    32. }
    33. public static String format(LocalDate localDate) {
    34. return localDate.format(DATE_FORMATTER);
    35. }
    36. /** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    37. public static LocalDate toLocalDate(LocalDateTime localDateTime) {
    38. return localDateTime.toLocalDate();
    39. }
    40. public static Instant toInstant(LocalDateTime localDateTime) {
    41. return localDateTime.toInstant(ZoneOffset.UTC);
    42. }
    43. public static Date toDate(LocalDateTime localDateTime) {
    44. return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    45. }
    46. /** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    47. public static LocalDateTime toLocalDateTime(LocalDate localDate) {
    48. return localDate.atStartOfDay();
    49. }
    50. public static Instant toInstant(LocalDate localDate) {
    51. return localDate.atStartOfDay().toInstant(ZoneOffset.UTC);
    52. }
    53. public static Date toDate(LocalDate localDate) {
    54. return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    55. }
    56. /** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    57. public static LocalDateTime toLocalDateTime(Instant instantWithoutZone) {
    58. return LocalDateTime.ofInstant(instantWithoutZone, ZoneOffset.UTC);
    59. }
    60. public static LocalDate toLocalDate(Instant instantWithoutZone) {
    61. return toLocalDateTime(instantWithoutZone).toLocalDate();
    62. }
    63. public static Date toDate(Instant instantWithoutZone) {
    64. return toDate(toLocalDateTime(instantWithoutZone));
    65. }
    66. }

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

    1. /**
    2. * @Description 日期时间工具类单测案例
    3. * @author xiao tang
    4. * @version 1.0.0
    5. * @createTime 2023年10月05日
    6. */
    7. public class BusiDateTimeUtilsTest {
    8. /** -------------------- 1. 当前日期时间操作 -------------------- */
    9. @Test
    10. public void test1() {
    11. // 获取当前日期时间
    12. String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
    13. System.out.println("nowLocalDateTimeStr="+nowLocalDateTimeStr); // 2023-10-05 21:28:09
    14. // 获取当前日期
    15. String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
    16. System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    17. }
    18. /** -------------------- 2. 字符串解析为日期时间对象 -------------------- */
    19. @Test
    20. public void test2() {
    21. // 解析当前日期时间
    22. String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
    23. System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:29:32
    24. LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
    25. System.out.println(parsedLocalDateTime); // 2023-10-05T21:29:32
    26. // 解析当前日期
    27. String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
    28. System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    29. LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
    30. System.out.println(parsedLocalDate); // 2023-10-05
    31. }
    32. /** -------------------- 3. 日期时间对象格式化为字符串 -------------------- */
    33. @Test
    34. public void test3() {
    35. // 格式化当前日期时间对象为字符串
    36. String nowLocalDateTimeStr = BusiDateTimeUtils.getNowLocalDateTimeStr();
    37. System.out.println("nowLocalDateTimeStr="+ nowLocalDateTimeStr); // 2023-10-05 21:35:19
    38. LocalDateTime parsedLocalDateTime = BusiDateTimeUtils.parseLocalDateTime(nowLocalDateTimeStr);
    39. String formatedLocalDateTime = BusiDateTimeUtils.format(parsedLocalDateTime);
    40. System.out.println(formatedLocalDateTime); // 2023-10-05 21:35:19
    41. // 格式化当前日期对象为字符串
    42. String nowLocalDateStr = BusiDateTimeUtils.getNowLocalDateStr();
    43. System.out.println("nowLocalDateStr=" + nowLocalDateStr); // 2023-10-05
    44. LocalDate parsedLocalDate = BusiDateTimeUtils.parseLocalDate(nowLocalDateStr);
    45. String formatedLocalDate = BusiDateTimeUtils.format(parsedLocalDate);
    46. System.out.println(formatedLocalDate); // 2023-10-05
    47. }
    48. /** -------------------- 4. LocalDateTime 转为其他日期时间类型 -------------------- */
    49. @Test
    50. public void test4() {
    51. LocalDateTime nowLocalDateTime = LocalDateTime.now();
    52. System.out.println("nowLocalDateTimeStr="+BusiDateTimeUtils.format(nowLocalDateTime)); // 2023-10-05 21:37:14
    53. // LocalDateTime 转 LocalDate
    54. LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowLocalDateTime);
    55. LocalDate localDate2 = nowLocalDateTime.toLocalDate(); // 与上一行代码效果一样
    56. System.out.println("localDate=" + localDate); // 2023-10-05
    57. // LocalDateTime 转 Instant
    58. Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDateTime);
    59. System.out.println(nowInstant); // 2023-10-05T21:37:14.677Z
    60. // LocalDateTime 转 Date
    61. Date nowDate = BusiDateTimeUtils.toDate(nowLocalDateTime);
    62. System.out.println(nowDate); // Thu Oct 05 21:37:14 CST 2023
    63. }
    64. /** -------------------- 5. LocalDate 转为其他日期时间类型 -------------------- */
    65. @Test
    66. public void test5() {
    67. LocalDate nowLocalDate = LocalDate.now();
    68. System.out.println("nowLocalDateStr="+BusiDateTimeUtils.format(nowLocalDate)); // 2023-10-05
    69. // LocalDate 转 LocalDateTime
    70. LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowLocalDate);
    71. System.out.println("localDateTime=" + localDateTime); // 2023-10-05T00:00
    72. // LocalDate 转 Instant
    73. Instant nowInstant = BusiDateTimeUtils.toInstant(nowLocalDate);
    74. System.out.println(nowInstant); // 2023-10-05T00:00
    75. // LocalDate 转 Date
    76. Date nowDate = BusiDateTimeUtils.toDate(nowLocalDate);
    77. System.out.println(nowDate); // Thu Oct 05 00:00:00 CST 2023
    78. }
    79. /** -------------------- 6. Instant 转为其他日期时间类型 -------------------- */
    80. @Test
    81. public void test6() {
    82. Instant nowInstantWithoutZone = LocalDateTime.now().toInstant(ZoneOffset.UTC);
    83. System.out.println("nowZonedInstant="+nowInstantWithoutZone); // 2023-10-05T22:00:54.783Z
    84. System.out.println("Instant.now()=" + Instant.now()); // 2023-10-05T14:00:54.798Z(注意这里晚了8个小时)
    85. // Instant 转 LocalDateTime
    86. LocalDateTime localDateTime = BusiDateTimeUtils.toLocalDateTime(nowInstantWithoutZone);
    87. System.out.println("localDateTime=" + localDateTime); // 2023-10-05T22:00:54.783
    88. // Instant 转 LocalDate
    89. LocalDate localDate = BusiDateTimeUtils.toLocalDate(nowInstantWithoutZone);
    90. System.out.println("localDate=" + localDate); // 2023-10-05
    91. // Instant 转 Date
    92. Date date = BusiDateTimeUtils.toDate(nowInstantWithoutZone);
    93. System.out.println("date=" + date); // date=Thu Oct 05 22:00:54 CST 2023
    94. }
    95. }

  • 相关阅读:
    面试--redis基础
    微信小程序修改vant组件样式
    消极型人格分析,如何改变消极型性格?
    【SSH远程登录长时间连接后容易出现自动断开的解决方案】
    位图原理及实现
    vue解决Not allowed to load local resource
    (13.1)Latex符号表示及公式撰写
    【NestJS系列】核心概念:Module模块
    【Ajax进阶】跨域和JSONP的学习
    阿里云Hologres助力好未来网校实时数仓降本增效
  • 原文地址:https://blog.csdn.net/PacosonSWJTU/article/details/133588296