从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java数据类型

    • Java 多版本配置
    • 面向对象

    • Java核心类

    • IO

    • Java与时间

      • Java 中的时间
      • Date、Calendar 和 TimeZone
      • LocalDate、LocalTime 和 LocalDateTime
        • 入门案例
        • 指定时间
        • 调整日期和时间
        • 比较时间
        • 日期和时间的加减
        • 转换时区
        • 小结
      • 一些日期的枚举类
      • DateTimeFormatter
      • 时间调节器
      • Duration 和 Period
      • ZonedDateTime
      • Instant 时刻
      • Java 新旧时间 API 转换
    • 异常处理

    • 哈希和加密算法

    • Java8新特性

    • 网络编程

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • Java与时间
2022-12-27
目录

LocalDate、LocalTime 和 LocalDateTime

# 52.LocalDate、LocalTime 和 LocalDateTime

由于 Java 旧的时间 API 不好用,市面上出现了不少关于时间的 API,例如开源的 Joda Time (opens new window),应用广泛;JDK 团队邀请 Joda Time 的作者 Stephen Colebourne 共同设计了 java.time API,并在 Java8 引入。

主要的类如下:

  • 本地日期和时间:LocalDate,LocalTime,LocalDateTime;
  • DateTimeFormatter:格式化日期,可取代 SimpleDateFormat;
  • 带时区的日期和时间:ZonedDateTime;
  • 时刻:Instant;
  • 时区:ZoneId,ZoneOffset;
  • 时间间隔:Duration和 Period;

其他改进:

  • 严格区分了时刻、本地日期、本地时间和带时区的日期时间
  • 提供了方便的日期和时间运算的 API
  • Month 的范围用 1~12 表示 1 月到 12 月 ,Week 的范围用 1~7 表示周一到周日(这才合理嘛!😄)
  • 新 API 的类型几乎全部是不变类型(和 String 类似),可以放心使用不必担心被修改。

我们首先介绍这 3 个:

  • LocalDate,表示本地日期
  • LocalTime,表示本地时间
  • LocalDateTime,表示本地日期和时间
  • 实际上,看 LocalDateTime 的源码可以发现,LocalDateTime 是由 LocalDate 和 LocalTime 来表示的

# 入门案例

    LocalDate d = LocalDate.now();
    LocalTime t = LocalTime.now();
    LocalDateTime dt = LocalDateTime.now();

    System.out.println(d);    //2022-12-22
    System.out.println(t);    //12:53:28.332
    System.out.println(dt);    //2022-12-22T12:53:28.332
1
2
3
4
5
6
7

说明:

  • 本地日期和时间通过 now() 获取到的总是以当前默认时区返回的
  • 打印的格式和旧的不同,默认严格按照 ISO 8601 (opens new window) 规定的日期和时间格式进行打印

获取一个某个时间的属性:

  • 获得年份: getYear()
  • 获得当前的月份(枚举值):getMonth()
  • 获得月份的数值:getMonthValue()
  • 获得今天是本月的第几天: getDayOfMonth()
  • 获得当前时间的小时:getHour()
  • 获得当前时间的分钟:getMinute()
  • 获得当前时间的秒: getSecond()
  • 获得今天是本年的第几天: getDayOfYear()
  • 获得今天是本周的第几天: getDayOfWeek()

还可以用 get 方法获取指定字段的 int 值:

LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 2, 3, 4, 56789);//2022-1-1 2:3:1
int i1 = ldt.get(ChronoField.MINUTE_OF_DAY);    //123  指的是目前已经过了2*小时 + 3分钟= 123分钟了
int i2 = ldt.get(ChronoField.MINUTE_OF_HOUR);    //3 指的是目前在当前这个小时内,已经过了3分钟
1
2
3

关于 ChronoField 类,我们下回分解

# 指定时间

我们可以在创建对象的时候,指定时间:

    LocalDate d2 = LocalDate.of(2022, 5, 21);
    LocalTime t2 = LocalTime.of(13,14, 15);
    LocalDateTime dt2 = LocalDateTime.of(2022,5, 21, 13, 14, 15);
    LocalDateTime dt3 = LocalDateTime.of(d2, t2);

    System.out.println("d2: " + d2);    //d2: 2022-05-21
    System.out.println("t2: " + t2);    //t2: 13:14:15
    System.out.println("dt2: " + dt2);    //dt2: 2022-05-21T13:14:15
    System.out.println("dt3: " + dt3);    //dt3: 2022-05-21T13:14:15
1
2
3
4
5
6
7
8
9

第 4 行我们用了 LocalDate 和 LocalTime 创建 LocalDateTime ,也可以反过来:

    LocalDate d3 = dt2.toLocalDate();
    LocalTime t3 = dt2.toLocalTime();
    System.out.println("d3: " + d3);    //d3: 2022-05-21
    System.out.println("t3: " + t3);    //t3: 13:14:15
1
2
3
4

还可以通过字符串来创建:

    // 通过字符串创建对象
    LocalDateTime dt4 = LocalDateTime.parse("2022-5-21T21:13:14");
    LocalDate d4 = LocalDate.parse("2022-5-21");
    LocalTime t6 = LocalTime.parse("15:16:17");
1
2
3
4

注意 ISO 8601 规定的日期和时间分隔符是 T。标准格式如下:

  • 日期:yyyy-MM-dd
  • 时间:HH:mm:ss
  • 带毫秒的时间:HH:mm:ss.SSS
  • 日期和时间:yyyy-MM-dd'T'HH:mm:ss
  • 带毫秒的日期和时间:yyyy-MM-dd'T'HH:mm:ss.SSS

其他注意事项:

构造方法得是合理的参数值,例如小时的范围是 0~23,如果超过(例如设置成 52),运行的时候会抛出异常:

Exception in thread "main" java.time.DateTimeException: Invalid value for HourOfDay (valid values 0 - 23): 52
        at java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311)
        at java.time.temporal.ChronoField.checkValidValue(ChronoField.java:703)
        at java.time.LocalTime.of(LocalTime.java:317)
        at TestLocalDateTime.main(TestLocalDateTime.java:17)
1
2
3
4
5

# 调整日期和时间

可以用 withXXX() 调整时间和日期

  • 调整年:withYear()
  • 调整月:withMonth()
  • 调整日:withDayOfMonth()
  • 调整时:withHour(). 例如:withHour(15) 会把 10:11:12 变为 15:11:12:
  • 调整分:withMinute()
  • 调整秒:withSecond()
    LocalDateTime dt = LocalDateTime.of(2022,5, 21, 13, 14, 15);
    dt = dt.withYear(2122);
    dt = dt.withHour(05); //调整成5点
    System.out.println(dt); //2122-05-21T05:14:15
1
2
3
4

注意:月份的加减会自动调整日期,例如从 10 月 31 日减去一个月,会得到 9 月 30 日,因为 9 月没有 31

LocalDateTime 还有一个通用的 with() 方法允许我们做更复杂的调整,我们后面会提到。

# 比较时间

由于代码执行需要一定的时间,需要注意分开创建的时间对象是不一样的(1 毫秒不同也不行,除非你能保证两者运行的时间差距在 1 毫秒,一些性能好的计算机可能做到,但我们不能把希望寄托于未知 🧐)。

    LocalTime t4 = LocalTime.now();
    LocalTime t5 = LocalTime.now();
    System.out.println(t4.compareTo(t5));  //-1
1
2
3

我们还可以用 isBefore()、isAfter() 方法来判断,其返回 Boolean 值

# 日期和时间的加减

LocalDateTime 提供了方便的加减方法:

LocalDateTime dt = LocalDateTime.of(2022,5, 21, 13, 14, 15);
dt = dt.plusDays(5);  // sub 5 days
dt = dt.plusDays(1);  // add 1 day
dt = dt.plusHours(1); //sub 1 hour
dt = dt.minusHours(3); //add 3 hours
System.out.println(dt);    //2022-05-27T11:14:15
1
2
3
4
5
6

minus 有减法的意思。

可以对秒数、分钟、小时、天数、周数、月份、年份进行加减。

可以用链式调用,简化代码:

dt = LocalDateTime.of(2022,5, 21, 13, 14, 15);
dt = dt.plusDays(5).minusDays(1).plusHours(1).minusHours(3);
System.out.println(dt); //2022-05-25T11:14:15
1
2
3

注意:月份的加减会自动调整日期,例如从 10 月 31 日减去一个月,会得到 9 月 30 日,因为 9 月没有 31

# 转换时区

LocalDateTime 无法与时间戳进行转换,因为 LocalDateTime 没有时区,无法确定某一时刻。

后面我们会介绍 ZonedDateTime,其相当于 LocalDateTime 加时区的组合,可以与 long 表示的时间戳进行转换。

# 小结

LocalDate,LocalTime,LocalDateTime 的常用方法如下:

方法名 用处 示例
now() 获取当前默认时区的当前时间 LocalDate.now();
getXXX() 获取时间的某个字段 getYear() 获取年份
of() 指定时间 LocalDate.of(2022, 5, 21);
parse(String s) 根据字符串来指定时间 LocalDate.parse("2022-5-21");
withXXX() 调整时间和日期 dt.withYear(2122);
compareTo() isBefore() isAfter() 比较时间 t4.compareTo(t5)
plusXXX(), minusXXX() 加减时间 dt.plusDays(5)
上次更新: 2024/10/1 16:19:31
Date、Calendar 和 TimeZone
一些日期的枚举类

← Date、Calendar 和 TimeZone 一些日期的枚举类→

最近更新
01
吐槽一下《僵尸校园》
05-15
02
2025 年 4 月记
04-30
03
山西大同 “订婚强奸案” 将会给整个社会带来的影响有多严重? - 知乎 转载
04-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式