jdk1.8 LocalTime、LocalDate、LocalDateTime 使用大全

打印 上一主题 下一主题

主题 909|帖子 909|积分 2727

目录

LocalTime、LocalDate、LocalDateTime 区别

LocalTime、LocalDate、LocalDateTime是java8对日期、时间提供的新接口。
jdk1.8 之前的 SimpleDateFormat 是线程不安全的。
DateTimeFormatter是线程安全的

  • LocalTime 用于时刻的计算(带有毫秒)
  • LocalDate 用于日期的计算
  • LocalDateTime 用于 日期+时刻 的计算
  • 额外补充 时间类型 默认格式:

    • Date Tue Feb 01 00:00:00 CST 2022
    • Timestamp 2022-01-01 00:00:00.0
    • LocalDateTime 2022-01-01T00:00:00.000

LocalTime、LocalDate、LocalDateTime 使用

now 获取当前 时刻、日期、时间
  1. LocalTime now = LocalTime.now();
  2. >>> 获取当前时刻: 10:20:00.856
  3. LocalDate now = LocalDate.now();
  4. >>> 获取当前日期: 2023-04-13
  5. LocalDateTime now = LocalDateTime.now();
  6. >>> 获取当前时间: 2023-04-13T17:29:29.357
复制代码

  • LocalTime 获取当前时刻默认会带有毫秒,如果不需要毫秒的话,可以通过设置纳秒为0 保留秒 1秒 = 十亿纳秒 例如:LocalTime.now().withNano(0);
  • LocalDateTime 获取当前日期,默认toString会带有 T 用于区分 日期与时刻,在项目中,可以通过全局序列化,进行统一的时间格式输出为 yyyy-MM-dd HH:mm:ss
of 获取指定 时刻、日期、时间
  1. LocalTime ofTime = LocalTime.of(12, 0, 0);
  2. >>> 获取指定时刻: 12:00
  3. LocalDate ofTime = LocalDate.of(2023, 4, 13);
  4. >>> 获取指定日期: 2023-04-13
  5. LocalDateTime ofTime = LocalDateTime.of(2023,4,13,6,10,20,123);
  6. >>> 获取指定时间: 2023-04-13T06:10:20.000000001
  7. LocalDateTime ofTime = LocalDateTime.of(LocalDate.of(2023, 4, 13),LocalTime.of(12, 0, 0));
  8. >>> 获取指定时间: 2023-04-13T12:00
复制代码

  • LocalDateTime.of 的参数单位分别为 年、月、日、小时、分钟、秒、纳秒
  • LocaTime 常用常量
  1. // 一天开始时的午夜时刻,“00:00”
  2. LocalTime.MIDNIGHT
  3. // 支持的最小时刻 “00:00” 这是一天开始时的时刻。
  4. LocalTime.MIN
  5. // 支持的最大时刻 “23:59:59.999999999” 这是一天结束时的时刻
  6. LocalTime.MAX
  7. // 中午的时刻 “12:00”
  8. LocalTime.NOON
复制代码

  • 一些比较特殊的获取方式,例如:
  1. // 根据秒数 获取 时刻 例如:第 150 秒的时刻是 00:02:30 (相似方法同理)
  2. LocalTime.ofSecondOfDay(150)
  3. >>> 获取指定时刻: 00:02:30
  4. // 获取指定年限 + 天数 得到日期,例如:获取2023年第120天的日期(相似方法同理)
  5. LocalDate.ofYearDay(2023, 120);
  6. >>> 获取2023年第120天的日期: 2023-04-30
复制代码
plus || minus 增加或者减少
  1. // 增加 1 星期(相似方法同理)
  2. LocalDateTime.now().plusWeeks(1);
  3. // 增加 1 天(相似方法同理)
  4. LocalDate.now().plusDays(1);
  5. // 增加 1 小时(相似方法同理)
  6. LocalTime.now().plusHours(1);
  7. LocalDateTime.now().plus(10L, ChronoUnit.DAYS);
  8. // 与之相反的 minus 就是减少的意思 不再举例子说明
复制代码
更改指定的 时间
  1. // 直接改变 指定时刻
  2. LocalTime.now().withHour(12);
  3. >>> 09:57:23.505 -> 12:57:23.505
  4. // 直接改变 指定日期
  5. LocalDate.now().withDayOfMonth(2);
  6. >>> 2023-04-14 -> 2023-04-02
  7. // 直接改变 指定时间
  8. LocalDateTime.now().withYear(2024);
  9. >>> 2023-04-14T09:59:20.034 -> 2024-04-14T09:59:20.034
复制代码

  • 其他with开头的方法大同小异,但要注意的是,如果改变的值是错误的时间,会报错的,例如:在2月份设置31天
isAfter || isBefore 比较大小
  1. // 8:00
  2. LocalTime time_8 = LocalTime.of(8, 0, 0);
  3. // 9:00
  4. LocalTime time_9 = time_8.plusHours(1);
  5. boolean after = time_9.isAfter(time_8);
  6. >>> 判断 9:00 是不是在 8:00 之后 >> true
  7. boolean before = time_9.isBefore(time_8);
  8. >>> 判断 9:00 是不是在 8:00 之前 >> false
复制代码

  • isAfter || isBefore 是无法比较是否相等的,LocalDate 和 LocalDateTime 均有此方法,用法都一样
compareTo 时间比较
  1. // 8:00
  2. LocalTime time_8 = LocalTime.of(8, 0, 0);
  3. // 9:00
  4. LocalTime time_9 = time_8.plusHours(1);
  5. int i = time_9.compareTo(time_8);
  6. >>> i = 1
  7. int i = time_8.compareTo(time_9);
  8. >>> i = -1
  9. int i = time_8.compareTo(LocalTime.of(8, 0, 0));
  10. >>> i = 0
复制代码

  • 此方法可对比出时间是否相等,假设 A.compareTo(B);

    • A > B = 1
    • A < B = -1
    • A = B = 0

LocalTime、LocalDate、LocalDateTime 相互转化
  1. // LocalTime + LocalDate = LocalDateTime
  2. LocalDateTime localDateTime = LocalTime.now().atDate(LocalDate.now());
  3. LocalDateTime localDateTime = LocalDate.now().atTime(LocalTime.now());
  4. LocalDateTime localDateTime = LocalDateTime.of(LocalTime.now(),LocalDate.now());
  5. // LocalDateTime 转 LocalDate
  6. LocalDate localDate = LocalDateTime.now().toLocalDate();
  7. // LocalDateTime 转 LocalTime
  8. LocalTime localTime = LocalDateTime.now().toLocalTime();
  9. // 获取今日开始时间 2023-04-21T00:00
  10. LocalDateTime localDateTime = LocalDate.now().atStartOfDay();
  11. // 获取今日开始时间 2023-04-21T00:00
  12. LocalDateTime startDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
  13. // 获取今日结束时间 2023-04-21T23:59:59.999999999
  14. LocalDateTime endDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
复制代码
String 与 LocalTime、LocalDate、LocalDateTime 相互转化

主要使用 format 和 parse 进行转换,使用方法基本相同
使用 DateTimeFormatter.ofPattern() 定义时间格式,再进行转换
DateTimeFormatter线程安全
format && parse
  1. LocalTime.now().toString;
  2. >>> 默认输出格式 10:50:25.323
  3. LocalDate.now().toString()
  4. >>> 默认输出格式 2023-04-14
  5. LocalDateTime.now().toString();
  6. >>> 默认输出格式 2023-04-14T15:59:40
  7. // LocalTime 转 String 自定义输出格式,例如:**时**分**秒 该转化的 00 不会被省略
  8. DateTimeFormatter localTimeFormat = DateTimeFormatter.ofPattern("HH时mm分ss秒");
  9. String time = LocalTime.now().format(localTimeFormat);
  10. >>> 09时11分00秒
  11. // LocalDateTime 转 String
  12. DateTimeFormatter localTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  13. String time = LocalDateTime.now().format(localTimeFormat);
  14. >>> 2023-04-14 15:59:40
  15. // String 转 LocalDateTime
  16. LocalDateTime time = LocalDateTime.parse("2023-04-14 15:59:40", localTimeFormat);
复制代码
Jackson 全局配置

在Stringboot 中,可自定义配置 Jackson 的序列化输出,使接口在 输入输出 统一规范
简单举个例子
  1.     @Bean // 装载配置
  2.     @Primary
  3.     @ConditionalOnMissingBean
  4.     public ObjectMapper objectMapper() {
  5.         ObjectMapper mapper = create();
  6.         log.info(">>>>> JackSon 全局设置成功,版本号:{}", mapper.version());
  7.         return mapper;
  8.     }
  9.     private static ObjectMapper create() {
  10.         ObjectMapper objectMapper = new ObjectMapper();
  11.         // 创建自定义 时间转换 模板
  12.         JavaTimeModule timeModule = new JavaTimeModule();
  13.         
  14.         // 定义统一的时间格式
  15.         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
  16.         // 序列化 添加 LocalDateTime 类 对应的时间格式
  17.         timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
  18.         // 反序列化  支持时间戳
  19.         timeModule.addDeserializer(LocalDateTime.class, new MillisOrLocalDateTimeDeserializer(dateTimeFormatter));
  20.         
  21.         // 定义统一的日期格式
  22.         DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.CHINA);
  23.         // 序列化 添加 LocalDate 类 对应的日期格式
  24.         timeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
  25.         // 反序列化
  26.         timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));
  27.         
  28.         // 注册自定义模板
  29.         objectMapper.registerModules(createJavaTimeModules());
  30.         return objectMapper;
  31.     }
复制代码
Date 与 LocalDate、LocalDateTime 相互转化
  1. // Date 转 LocalDateTime
  2. LocalDateTime localDateTime = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
  3. // LocalDateTime 转 Date
  4. Date date = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
  5. // Date转LocalDate
  6. LocalDate localDate = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
  7. // LocalDate 转 Date  需要先将 LocalDate 转 LocalDateTime
  8. Date date= Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
复制代码
Long 与 LocalDate、LocalDateTime 相互转化

ZoneOffset.of("+8") 和 ZoneOffset.ofHours(8) 意义相同
  1. long timeMillis = System.currentTimeMillis();
  2. // 时间戳(Long) 转 LocalDateTime
  3. LocalDateTime localDateTime = Instant.ofEpochMilli(timeMillis).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
  4. // LocalDateTime 转 时间戳(Long) 秒级
  5. Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));
  6. // LocalDateTime 转 时间戳(Long) 毫秒级
  7. Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
  8. // 时间戳(Long) 转 LocalDate
  9. LocalDate localDate = Instant.ofEpochMilli(timeMillis).atZone(ZoneOffset.ofHours(8)).toLocalDate();
  10. // LocalDate 转 时间戳(Long) 秒级
  11. Long second =  LocalDate.now().atStartOfDay().toEpochSecond(ZoneOffset.ofHours(8));
  12. // LocalDate 转 时间戳(Long) 毫秒级
  13. Long milliSecond = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
复制代码
常用时间操作方法

两个时间相差时间

Period.between(star,end)

统计 相差几年几个月几天
获得一个由两个日期之间的年数、月数和天数组成的周期,如果结束在开始之前,则此方法的结果可能是一个负周期。负号在每一年、每一个月和每一天都是一样的。
  1. LocalDateTime star = LocalDateTime.of(2022, 3, 15, 16, 37, 10);
  2. LocalDateTime end = LocalDateTime.of(2024, 4, 20, 16, 37, 10);
  3. Period period = Period.between(star.toLocalDate(), end.toLocalDate());
  4. System.out.println(">>> 两个时间相差:" + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "日");
  5. >>> 两个时间相差:2年1月5日
复制代码
LocalDate.until


  • 方法1:
    Period until(ChronoLocalDate endDateExclusive);
    与 Period.between() 的使用相同类似,统计 相差几年几个月几天,可参考上一个案例
  • 方法2:
    long until(Temporal endExclusive, TemporalUnit unit);
    支持指定单位(按年或按月或按天)分别统计
  1. // ChronoUnit 可选择要计算的日期单位 年、月、日、小时、分钟 等等
  2. LocalDateTime star = LocalDateTime.of(2024, 3, 20, 16, 37, 10);
  3. LocalDateTime end = LocalDateTime.of(2024, 3, 21, 16, 37, 10);
  4. long until = star.until(end, ChronoUnit.DAYS);
  5. System.out.println(">>> 两个时间相差:" + until + "天");
  6. >>> 两个时间相差:1天
  7. // 使用 LocalDateTime 计算相隔日期,即使差了 1分钟 1毫秒 也不会计算1天
  8. LocalDateTime star = LocalDateTime.of(2024, 3, 20, 16, 37, 10);
  9. LocalDateTime end = LocalDateTime.of(2024, 3, 21, 16, 37, 9);
  10. long until = star.until(end, ChronoUnit.DAYS);
  11. System.out.println(">>> 两个时间相差:" + until + "天");
  12. >>> 两个时间相差:0天
  13. // 使用 LocalDate 计算相隔时差
  14. LocalDate star = LocalDate.of(2024, 3, 20);
  15. LocalDate end = LocalDate.of(2024, 3, 21);
  16. long until = star.until(end, ChronoUnit.DAYS);
  17. System.out.println(">>> 两个时间相差:" + until + "天");
  18. >>> 两个时间相差:1天
复制代码
Duration.between(star,end)

专业计算相隔时差,支持指定单位转化,天 到 纳秒 单位都支持
只能用 LocalDateTime
  1. LocalDateTime star = LocalDateTime.of(2024, 3, 20, 16, 37, 10);
  2. LocalDateTime end = LocalDateTime.of(2024, 3, 21, 16, 37, 10);
  3. Duration duration = Duration.between(star, end);
  4. System.out.println(">>> 两个时间相差:" + duration.toDays() + "天");
  5. System.out.println(">>> 两个时间相差:" + duration.toHours() + "小时");
  6. System.out.println(">>> 两个时间相差:" + duration.toMinutes() + "分钟");
  7. System.out.println(">>> 两个时间相差:" + duration.toMillis() + "毫秒");
  8. System.out.println(">>> 两个时间相差:" + duration.toNanos() + "纳秒");
  9. >>> 两个时间相差:1天
  10. >>> 两个时间相差:24小时
  11. >>> 两个时间相差:1440分钟
  12. >>> 两个时间相差:86400000毫秒
  13. >>> 两个时间相差:86400000000000纳秒
复制代码
TemporalAdjuster

TemporalAdjuster 是函数接口,在TemporalAdjusters 类中有很多预定义的实现。TemporalAdjuster仅有一个带Temporal对象参数的抽象方法adjustInto()。
TemporalAdjuster可以执行复杂的日期操作,例如,可以获得下一个星期日对于日期、当月的最后一天、下一年的第一天。当然也可以通过旧的java.util.Calendar api实现。不同的是,新api使用预定义的实现抽象出底层逻辑。
TemporalAdjusters 类中预定义实现

TemporalAdjusters类有很多预定义的static方法返回TemporalAdjuster对象,使用不同方式调节Temporal对象而与Temporal实现无关。
  1. // 也可以使用 LocalDateTime 带时刻
  2. LocalDate localDate = LocalDate.now();
  3. // 当月第一天
  4. localDate.with(TemporalAdjusters.firstDayOfMonth());
  5. // 当月最后一天
  6. localDate.with(TemporalAdjusters.lastDayOfMonth());
  7. // 今年的第一天
  8. localDate.with(TemporalAdjusters.firstDayOfYear());
  9. // 今年的最后一天
  10. localDate.with(TemporalAdjusters.lastDayOfYear());
  11. // 下个月的第一天
  12. localDate.with(TemporalAdjusters.firstDayOfNextMonth());
  13. // 下一年的第一天
  14. localDate.with(TemporalAdjusters.firstDayOfNextYear());
  15. // 这个月的最后一个星期日
  16. localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY));
  17. // 这个月的倒数第二个星期日
  18. localDate.with(TemporalAdjusters.dayOfWeekInMonth(-2,DayOfWeek.SUNDAY));
  19. // 这个月的第一个星期日
  20. localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY));
  21. // 这个月的第二个星期日
  22. localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY));
  23. // 下个月的最后一个星期日
  24. localDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
  25. // 上个星期五
  26. localDate.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
  27. // 上个最近的星期五,包含今天的判断 如果今天星期五 则会返回今天日期
  28. localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY));
  29. // 下个星期一
  30. localDate.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
  31. // 下个最近的星期一,包含今天的判断 如果今天是星期一 则会返回今天日期
  32. localDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表