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

科技资讯 投稿 8700 0 评论

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

目录
    LocalTime、LocalDate、LocalDateTime 区别
  • LocalTime、LocalDate、LocalDateTime 使用
    • now 获取当前 时刻、日期、时间
    • of 获取指定 时刻、日期、时间
    • plus || minus 增加或者减少
    • 更改指定的 时间
    • isAfter || isBefore 比较大小
    • compareTo 时间比较
  • LocalTime、LocalDate、LocalDateTime 相互转化
  • String 与 LocalTime、LocalDate、LocalDateTime 相互转化
      format && parse
    • Jackson 全局配置
  • Date 与 LocalDate、LocalDateTime 相互转化
  • Long 与 LocalDate、LocalDateTime 相互转化
  • 常用时间操作方法
      两个时间相差时间
      • Period.between(star,end
      • LocalDate.until
      • Duration.between(star,end
    • TemporalAdjuster
    • TemporalAdjusters 类中预定义实现

LocalTime、LocalDate、LocalDateTime 区别

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 获取当前 时刻、日期、时间

LocalTime now = LocalTime.now(;
>>> 获取当前时刻: 10:20:00.856

LocalDate now = LocalDate.now(;
>>> 获取当前日期: 2023-04-13

LocalDateTime now = LocalDateTime.now(;
>>> 获取当前时间: 2023-04-13T17:29:29.357
    LocalTime 获取当前时刻默认会带有毫秒,如果不需要毫秒的话,可以通过设置纳秒为0 保留秒 1秒 = 十亿纳秒 例如:LocalTime.now(.withNano(0;
  • LocalDateTime 获取当前日期,默认toString会带有 T 用于区分 日期时刻,在项目中,可以通过全局序列化,进行统一的时间格式输出为 yyyy-MM-dd HH:mm:ss

of 获取指定 时刻、日期、时间

LocalTime ofTime = LocalTime.of(12, 0, 0;
>>> 获取指定时刻: 12:00

LocalDate ofTime = LocalDate.of(2023, 4, 13;
>>> 获取指定日期: 2023-04-13

LocalDateTime ofTime = LocalDateTime.of(2023,4,13,6,10,20,123;
>>> 获取指定时间: 2023-04-13T06:10:20.000000001
LocalDateTime ofTime = LocalDateTime.of(LocalDate.of(2023, 4, 13,LocalTime.of(12, 0, 0;
>>> 获取指定时间: 2023-04-13T12:00
    LocalDateTime.of 的参数单位分别为 年、月、日、小时、分钟、秒、纳秒
  • LocaTime 常用常量
// 一天开始时的午夜时刻,“00:00”
LocalTime.MIDNIGHT
// 支持的最小时刻 “00:00” 这是一天开始时的时刻。
LocalTime.MIN
// 支持的最大时刻 “23:59:59.999999999” 这是一天结束时的时刻
LocalTime.MAX
// 中午的时刻 “12:00”
LocalTime.NOON
    一些比较特殊的获取方式,例如:
// 根据秒数 获取 时刻 例如:第 150 秒的时刻是 00:02:30 (相似方法同理)
LocalTime.ofSecondOfDay(150
>>> 获取指定时刻: 00:02:30

// 获取指定年限 + 天数 得到日期,例如:获取2023年第120天的日期(相似方法同理)
LocalDate.ofYearDay(2023, 120;
>>> 获取2023年第120天的日期: 2023-04-30

plus || minus 增加或者减少

// 增加 1 星期(相似方法同理)
LocalDateTime.now(.plusWeeks(1;
// 增加 1 天(相似方法同理)
LocalDate.now(.plusDays(1;
// 增加 1 小时(相似方法同理)
LocalTime.now(.plusHours(1;

LocalDateTime.now(.plus(10L, ChronoUnit.DAYS;

// 与之相反的 minus 就是减少的意思 不再举例子说明

更改指定的 时间

// 直接改变 指定时刻
LocalTime.now(.withHour(12;
>>> 09:57:23.505 -> 12:57:23.505

// 直接改变 指定日期
LocalDate.now(.withDayOfMonth(2;
>>> 2023-04-14 -> 2023-04-02

// 直接改变 指定时间
LocalDateTime.now(.withYear(2024;
>>> 2023-04-14T09:59:20.034 -> 2024-04-14T09:59:20.034
    其他with开头的方法大同小异,但要注意的是,如果改变的值是错误的时间,会报错的,例如:在2月份设置31天

isAfter || isBefore 比较大小

// 8:00
LocalTime time_8 = LocalTime.of(8, 0, 0;
// 9:00
LocalTime time_9 = time_8.plusHours(1;

boolean after = time_9.isAfter(time_8;
>>> 判断 9:00 是不是在 8:00 之后 >> true

boolean before = time_9.isBefore(time_8;
>>> 判断 9:00 是不是在 8:00 之前 >> false
    isAfter || isBefore 是无法比较是否相等的,LocalDateLocalDateTime 均有此方法,用法都一样

compareTo 时间比较

// 8:00
LocalTime time_8 = LocalTime.of(8, 0, 0;
// 9:00
LocalTime time_9 = time_8.plusHours(1;

int i = time_9.compareTo(time_8;
>>> i = 1

int i = time_8.compareTo(time_9;
>>> i = -1

int i = time_8.compareTo(LocalTime.of(8, 0, 0;
>>> i = 0
    此方法可对比出时间是否相等,假设 A.compareTo(B;
    • A > B = 1
    • A < B = -1
    • A = B = 0

LocalTime、LocalDate、LocalDateTime 相互转化

// LocalTime + LocalDate = LocalDateTime
LocalDateTime localDateTime = LocalTime.now(.atDate(LocalDate.now(;
LocalDateTime localDateTime = LocalDate.now(.atTime(LocalTime.now(;
LocalDateTime localDateTime = LocalDateTime.of(LocalTime.now(,LocalDate.now(;

// LocalDateTime 转 LocalDate
LocalDate localDate = LocalDateTime.now(.toLocalDate(;

// LocalDateTime 转 LocalTime
LocalTime localTime = LocalDateTime.now(.toLocalTime(;

// 获取今日开始时间 2023-04-21T00:00
LocalDateTime localDateTime = LocalDate.now(.atStartOfDay(;
// 获取今日开始时间 2023-04-21T00:00
LocalDateTime startDateTime = LocalDateTime.of(LocalDate.now(, LocalTime.MIN;
// 获取今日结束时间 2023-04-21T23:59:59.999999999
LocalDateTime endDateTime = LocalDateTime.of(LocalDate.now(, LocalTime.MAX;

String 与 LocalTime、LocalDate、LocalDateTime 相互转化

主要使用 formatparse 进行转换,使用方法基本相同
使用 DateTimeFormatter.ofPattern( 定义时间格式,再进行转换
DateTimeFormatter线程安全

format && parse

LocalTime.now(.toString;
>>> 默认输出格式 10:50:25.323

LocalDate.now(.toString(
>>> 默认输出格式 2023-04-14

LocalDateTime.now(.toString(;
>>> 默认输出格式 2023-04-14T15:59:40

// LocalTime 转 String 自定义输出格式,例如:**时**分**秒 该转化的 00 不会被省略
DateTimeFormatter localTimeFormat = DateTimeFormatter.ofPattern("HH时mm分ss秒";
String time = LocalTime.now(.format(localTimeFormat;
>>> 09时11分00秒

// LocalDateTime 转 String
DateTimeFormatter localTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss";
String time = LocalDateTime.now(.format(localTimeFormat;
>>> 2023-04-14 15:59:40

// String 转 LocalDateTime
LocalDateTime time = LocalDateTime.parse("2023-04-14 15:59:40", localTimeFormat;

Jackson 全局配置

在Stringboot 中,可自定义配置 Jackson 的序列化输出,使接口在 输入输出 统一规范
简单举个例子

    @Bean // 装载配置
    @Primary
    @ConditionalOnMissingBean
    public ObjectMapper objectMapper( {
        ObjectMapper mapper = create(;
        log.info(">>>>> JackSon 全局设置成功,版本号:{}", mapper.version(;
        return mapper;
    }

    private static ObjectMapper create( {
        ObjectMapper objectMapper = new ObjectMapper(;
        // 创建自定义 时间转换 模板
        JavaTimeModule timeModule = new JavaTimeModule(;
        
        // 定义统一的时间格式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA;
        // 序列化 添加 LocalDateTime 类 对应的时间格式 
        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter;
        // 反序列化  支持时间戳
        timeModule.addDeserializer(LocalDateTime.class, new MillisOrLocalDateTimeDeserializer(dateTimeFormatter;
        
        // 定义统一的日期格式
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.CHINA;
        // 序列化 添加 LocalDate 类 对应的日期格式
        timeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter;
        // 反序列化
        timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter;
        
        // 注册自定义模板
        objectMapper.registerModules(createJavaTimeModules(;
        return objectMapper;
    }

Date 与 LocalDate、LocalDateTime 相互转化

// Date 转 LocalDateTime
LocalDateTime localDateTime = new Date(.toInstant(.atZone(ZoneId.systemDefault(.toLocalDateTime(;
// LocalDateTime 转 Date
Date date = Date.from(LocalDateTime.now(.atZone(ZoneId.systemDefault(.toInstant(;

// Date转LocalDate
LocalDate localDate = new Date(.toInstant(.atZone(ZoneId.systemDefault(.toLocalDate(;
// LocalDate 转 Date  需要先将 LocalDate 转 LocalDateTime
Date date= Date.from(LocalDate.now(.atStartOfDay(ZoneId.systemDefault(.toInstant(;

Long 与 LocalDate、LocalDateTime 相互转化

ZoneOffset.of("+8" 和 ZoneOffset.ofHours(8 意义相同

long timeMillis = System.currentTimeMillis(;

// 时间戳(Long 转 LocalDateTime
LocalDateTime localDateTime = Instant.ofEpochMilli(timeMillis.atZone(ZoneOffset.ofHours(8.toLocalDateTime(;
// LocalDateTime 转 时间戳(Long 秒级
Long second = LocalDateTime.now(.toEpochSecond(ZoneOffset.ofHours(8;
// LocalDateTime 转 时间戳(Long 毫秒级
Long milliSecond = LocalDateTime.now(.toInstant(ZoneOffset.ofHours(8.toEpochMilli(;


// 时间戳(Long 转 LocalDate
LocalDate localDate = Instant.ofEpochMilli(timeMillis.atZone(ZoneOffset.ofHours(8.toLocalDate(;
// LocalDate 转 时间戳(Long 秒级
Long second =  LocalDate.now(.atStartOfDay(.toEpochSecond(ZoneOffset.ofHours(8;
// LocalDate 转 时间戳(Long 毫秒级
Long milliSecond = LocalDate.now(.atStartOfDay(.toInstant(ZoneOffset.ofHours(8.toEpochMilli(;

常用时间操作方法

两个时间相差时间

Period.between(star,end

统计 相差几年几个月几天
获得一个由两个日期之间的年数、月数和天数组成的周期,如果结束在开始之前,则此方法的结果可能是一个负周期。负号在每一年、每一个月和每一天都是一样的。

LocalDateTime star = LocalDateTime.of(2022, 3, 15, 16, 37, 10;
LocalDateTime end = LocalDateTime.of(2024, 4, 20, 16, 37, 10;
Period period = Period.between(star.toLocalDate(, end.toLocalDate(;
System.out.println(">>> 两个时间相差:" + period.getYears( + "年" + period.getMonths( + "月" + period.getDays( + "日";

>>> 两个时间相差:2年1月5日

LocalDate.until

    方法1:
    Period until(ChronoLocalDate endDateExclusive;
    Period.between( 的使用相同类似,统计 相差几年几个月几天,可参考上一个案例
  • 方法2:
    long until(Temporal endExclusive, TemporalUnit unit;
    支持指定单位(按年或按月或按天分别统计
// ChronoUnit 可选择要计算的日期单位 年、月、日、小时、分钟 等等
LocalDateTime star = LocalDateTime.of(2024, 3, 20, 16, 37, 10;
LocalDateTime end = LocalDateTime.of(2024, 3, 21, 16, 37, 10;
long until = star.until(end, ChronoUnit.DAYS;
System.out.println(">>> 两个时间相差:" + until + "天";
>>> 两个时间相差:1天

// 使用 LocalDateTime 计算相隔日期,即使差了 1分钟 1毫秒 也不会计算1天
LocalDateTime star = LocalDateTime.of(2024, 3, 20, 16, 37, 10;
LocalDateTime end = LocalDateTime.of(2024, 3, 21, 16, 37, 9;
long until = star.until(end, ChronoUnit.DAYS;
System.out.println(">>> 两个时间相差:" + until + "天";
>>> 两个时间相差:0天

// 使用 LocalDate 计算相隔时差
LocalDate star = LocalDate.of(2024, 3, 20;
LocalDate end = LocalDate.of(2024, 3, 21;
long until = star.until(end, ChronoUnit.DAYS;
System.out.println(">>> 两个时间相差:" + until + "天";
>>> 两个时间相差:1天

Duration.between(star,end

专业计算相隔时差,支持指定单位转化,天 到 纳秒 单位都支持
只能用 LocalDateTime

LocalDateTime star = LocalDateTime.of(2024, 3, 20, 16, 37, 10;
LocalDateTime end = LocalDateTime.of(2024, 3, 21, 16, 37, 10;
Duration duration = Duration.between(star, end;
System.out.println(">>> 两个时间相差:" + duration.toDays( + "天";
System.out.println(">>> 两个时间相差:" + duration.toHours( + "小时";
System.out.println(">>> 两个时间相差:" + duration.toMinutes( + "分钟";
System.out.println(">>> 两个时间相差:" + duration.toMillis( + "毫秒";
System.out.println(">>> 两个时间相差:" + duration.toNanos( + "纳秒";

>>> 两个时间相差:1天
>>> 两个时间相差:24小时
>>> 两个时间相差:1440分钟
>>> 两个时间相差:86400000毫秒
>>> 两个时间相差:86400000000000纳秒

TemporalAdjuster

TemporalAdjuster 是函数接口,在TemporalAdjusters 类中有很多预定义的实现。TemporalAdjuster仅有一个带Temporal对象参数的抽象方法adjustInto(。

TemporalAdjusters 类中预定义实现

TemporalAdjusters类有很多预定义的static方法返回TemporalAdjuster对象,使用不同方式调节Temporal对象而与Temporal实现无关。

// 也可以使用 LocalDateTime 带时刻
LocalDate localDate = LocalDate.now(; 
// 当月第一天
localDate.with(TemporalAdjusters.firstDayOfMonth(;
// 当月最后一天
localDate.with(TemporalAdjusters.lastDayOfMonth(;
// 今年的第一天
localDate.with(TemporalAdjusters.firstDayOfYear(;
// 今年的最后一天
localDate.with(TemporalAdjusters.lastDayOfYear(;
// 下个月的第一天
localDate.with(TemporalAdjusters.firstDayOfNextMonth(;
// 下一年的第一天
localDate.with(TemporalAdjusters.firstDayOfNextYear(;

// 这个月的最后一个星期日
localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY;
// 这个月的倒数第二个星期日
localDate.with(TemporalAdjusters.dayOfWeekInMonth(-2,DayOfWeek.SUNDAY;
// 这个月的第一个星期日
localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY;
// 这个月的第二个星期日
localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY;

// 下个月的最后一个星期日
localDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY;
// 上个星期五
localDate.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY;
// 上个最近的星期五,包含今天的判断 如果今天星期五 则会返回今天日期
localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY;
// 下个星期一
localDate.with(TemporalAdjusters.next(DayOfWeek.MONDAY;
// 下个最近的星期一,包含今天的判断 如果今天是星期一 则会返回今天日期
localDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY;

编程笔记 » jdk1.8 LocalTime/LocalDate/LocalDateTime 使用大全

赞同 (45) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽