日期 API
1. JDK8 之前
JDK8之前,java.util 下提供了一套日期相关类
- Date 日期类,它包含日期,时间,还有毫秒数,如果你只需日期或者时间那么有一些数据就没啥用
- 构造方法:Date()
- 构造方法:Date(long 毫秒)
- SimpleDateFormat 日期格式化类
- 日期转换成字符串(java.util.Date -> java.lang.String)
- 字符串转换成日期(java.lang.String -> java.util.Date)
- java.util.Calendar 日历类
- 并不好用,Hutool 这个工具包对 Date 和 Calendar 进行了封装,形成了 DateUtil。 他山之石
SimpleDateFormat 日期格式化
2. JDK8 之后
- JDK8 之后引入了一套新的 API,这套 API 最重要的升级点是:线程安全。
- java.util.Date 和 SimpleDateFormatter 都不是线程安全的,而 LocalDate 和 LocalTime 和最基本的 String 一样,是
不变类型
,不单线程安全
,而且不能修改。
- java.util.Date 和 SimpleDateFormatter 都不是线程安全的,而 LocalDate 和 LocalTime 和最基本的 String 一样,是
- 这套 API 包括:
- LocalDate 只操作日期
- LocalTime 只操作时间
- LocalDateTime 同时操作时间和日期。
- 可以看到,区别于以前一个 Date 包办日期到毫秒,新版 API 选择更灵活。
- DateTimeFormatter 日期格式化类
- Instant 时间戳信息
- Duration 计算两个时间对象之间的时间间隔,精度为纳秒
- Period 计算两个日期之间的时间间隔,以年、月、日为单位。新版 API 推算时间更加简单,就是因为有现成的 Period 静态方法可调用。
LocalDate
- LocalDate 表示一个格式为 yyyy-MM-dd 的日期,如 2021-06-13。
- LocalDate 是一个不可变的类。
- LocalDate 是一个基于值的类,要比较 LocalDate 的两个实例,我们应该使用它的 equals 方法。
- 我们可以从LocalDate中获取许多其他的日期字段,如年日(day-of-year)、周日(day-of-week)、月日(month-of-year)等等。
- LocalDate的格式可以通过DateTimeFormatter的格式方法来改变。
constructor
LocalDate 类的设计推荐使用静态工厂
方法来创建实例,而不是构造器
LocalDate today = new LocalDate(); // 通过构造器创建,不推荐
LocalDate today = LocalDate.now(); // 获取当前日期
// 指定日期创建:
LocalDate specificDate = LocalDate.of(year, month, day);
// 从 LocalDateTime 或 ZonedDateTime 转换:
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate dateFromLocalDateTime = localDateTime.toLocalDate();
// 解析字符串为日期:
LocalDate parsedDate = LocalDate.parse("2023-05-30", DateTimeFormatter.ISO_LOCAL_DATE);
// 使用parse()方法时,需要提供一个 DateTimeFormatter 来指定日期字符串的格式,如ISO 8601格式等。
// 但是也可以是自定义的格式
API
atTime、format、equals、compareTo等。
// LocalDate 的静态 API 即 LocalDate 的构造器,上述.
// LocalDate 的动态 API,用以操作 LocalDate 的实例。
获取日期
- 获取 LocalDate 实例的年、月、日的数字形式
int getYear();
int getMonthValue();
int getDayOfMonth();
LocalDate today = LocalDate.now();
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();
System.out.println(year + "-" + month + "-" + day); // out: 2024-5-30
- 获取 LocalDate 实例的月、日的单词形式
// 这两个方法返回的是枚举类型,其内定义了诸如 January、Febuary、Monday 等单词
DayOfWeek getDayOfWeek();
Month getMonth();
LocalDate now = LocalDate.now();
DayOfWeek dayOfWeek = now.getDayOfWeek();
Month month = now.getMonth();
System.out.println("dayOfWeek = " + dayOfWeek);// out: Thursday
System.out.println("month = " + month);// out: May
- 获取 LocalDate 实例的日在年、月、周的次序
int getDayOfMonth();
int getDayOfYear();
// 不能直接获取一周的第几天,只能先获取枚举类型再转 int
int getDayOfWeek().getValue();
LocalDate now = LocalDate.now();
int day = now.getDayOfMonth();
int day1 = now.getDayOfYear();
int day2 = now.getDayOfWeek().getValue();
System.out.println("day = " + day);
System.out.println("day1 = " + day1);
System.out.println("day2 = " + day2);
加减日期
// 加减日期有 4 种单位,分别是日/周/月/年
LocalDate plusDay/Week/Month/Year();
LocalDate minusDay/Week/Month/Year();
LocalDate now = LocalDate.now();
LocalDate yesterday = now.minusDays(1);
比较日期
格式化日期
// 分为两步,首先创建一个模式,然后用 LocalDate 对象调用 format 方法时将模式作为参数传入.
LocalDate now = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String formattedDate = now.format(formatter);
对于模式,既可以使用预定义的模式,也可以使用自定义的模式。
// 预定义的格式化器
DateTimeFormatter.ISO_LOCAL_DATE:格式为 yyyy-MM-dd
DateTimeFormatter.ISO_LOCAL_DATE_TIME:格式为 yyyy-MM-dd'T'HH:mm:ss
DateTimeFormatter.BASIC_ISO_DATE:格式为 yyyyMMdd
DateTimeFormatter.RFC_1123_DATE_TIME:格式为 Tue, 3 Jun 2008 11:05:30 GMT
// 自定义模式
// DateTimeFormatter.ofPattern(String pattern) 方法创建自定义的格式化器。
常用的模式字符包括:
y:年(如 yyyy 表示四位年)
M:月(如 MM 表示两位月)
d:日(如 dd 表示两位日)
E:星期(如 EEE 表示缩写的星期几,EEEE 表示全称的星期几)
H:小时(24 小时制,如 HH 表示两位小时)
h:小时(12 小时制,如 hh 表示两位小时)
m:分钟(如 mm 表示两位分钟)
s:秒(如 ss 表示两位秒)