- Date类
- 常用的方法
- Calendar类
- 常用的方法
- 重要的注意点
- add和roll方法的区别:
- 设置Calendar的容错性
- set()方法延迟修改
- Java8新增的日期、时间包
- Clock
- Duration
- Instant
- LocalDate
- LocalTime
- LocalDateTime
- MonthDay
- Year
- YearMonth
- ZonedDateTime
- ZoneId
- DayOfWeek
- Month
- LocalDateTime、LocalDate、Date的相互转换
- LocalDateTime 转 LocalDate
- LocalDateTime 转 Date
- LocalDate 转 LocalDateTime
- LocalDate 转 Date
- Date 转 LocalDateTime
- Date 转 LocalDate
Java在java.util包中提供了Date类,这个类封装了当前的日期和时间。
从JDK1.0开始就有了。
注意,Date不能实现国际化,偏移量也不统一,它的月份和小时都是从0开始的,月份的天数则是从1开始,年又是从1900开始的。
A year y is represented by the integer y - 1900.
A month is represented by an integer from 0 to 11; 0 is January, 1 is February, and so forth; thus 11 is December.
A date (day of month) is represented by an integer from 1 to 31 in the usual manner.
An hour is represented by an integer from 0 to 23. Thus, the hour from midnight to 1 a.m. is hour 0, and the hour from noon to 1 p.m. is hour 12.
该类的大部分方法都已过时。
常用的方法Date类支持两种构造函数:
- 第一个构造函数,初始化对象的当前日期和时间。
Date()
- 下面的构造函数接收一个参数等于自1970年1月1日 00:00:00 起已经过的毫秒数
Date(long millisec)
以下方法还可以使用:
| 方法 | 描述 |
|---|---|
| boolean after(Date date) | 如果调用Date对象包含或晚于指定的日期则返回true,否则,返回false。 |
| boolean before(Date date) | 如果调用Date对象包含或早于日期指定的日期返回true,否则,返回false。 |
| Object clone( ) | 重复调用Date对象。 |
| int compareTo(Date date) | 调用对象的值与日期比较。如果这两个值相等返回0。如果调用对象是早于日期返回一个负值。如果调用对象迟于日期返回正值。 |
| int compareTo(Object obj) | 以相同的compareTo(Date)操作 如果obj是一个类日期。否则,它会抛出一个ClassCastException。 |
| boolean equals(Object date) | 如果调用Date对象包含相同的时间及日期指定日期则返回true,否则,返回false。 |
| long getTime( ) | 返回自1970年1月1日起已经过的毫秒数。 |
| int hashCode( ) | 返回调用对象的哈希代码。 |
| void setTime(long time) | 设置所指定的时间,这表示从1970年1月1日从午夜的时间和日期以毫秒为单位经过的时间。 |
| String toString( ) | 调用Date对象转换为字符串,并返回结果。 |
从JDK1.1开始有的。用于表示日历,指最通用的 Gregorian Calendar,即公历,它是一个抽象类,它是所有日历类的模板,所以不能使用构造函数来创建Calendar对象,但它提供了几个静态方法来获取Calendar对象,根据TimeZone,Locale类获取特定的Calendar,如果不指定,则使用默认的TimeZone,Locale来创建Calendar。
// 创建一个默认的Calendar对象 Calendar calendar = Calendar.getInstance() // 从Calendar对象中取出Date对象 Date date = calendar.getTime() // 通过Date对象获得对应的Calendar对象 // Calendar没有直接接收Date对象的构造函数,因此只能通过下面的方式 Calendar calendar1 = Calendar.getInstance(); calendar1.setTime(date);
注意的时间字段:
Calendar.MonTH 代表月份,月份的起始是0,0代表1月。
Calendar.HOUR 12小时制的小时
Calendar.HOUR_OF_DAY 24小时制的小时
| 方法 | 描述 |
|---|---|
| add(int field, int amount) | 根据日历规则,给指定的日历字段添加(正数)或减去(负数)指定的时间量 |
| roll(int field, int amount) | 与add方法类似,区别在于,加上amount后超过了该字段所能表示的最大范围时,也不会向上一个字段进位。 |
| get(int field) | 返回指定日历字段的值 |
| getActualMaximum(int field) | 获取指定日历字段可能拥有的最大值 |
| getActualMinimum(int field) | 获取指定日历字段可能拥有的最小值 |
| set(int field, int value) | 将给定日历字段设置为给定值 |
| set(int year, int month, int date) | 设置Calendar对象的年、月、日 |
| set(int year, int month, int date, int hourOfDay, int minute, int second) | 设置Calendar对象的年、月、日、时、分、秒 |
add(int field, int amount)方法
根据日历规则,给指定的日历字段添加(正数)或减去(负数)指定的时间量
- 当被修改的字段超出它允许的范围时,会发生进位,即上一级字段也会发生变化
- 如果下一级的字段也要发生变化,那么改字段也会修正到变化最小的值。
Calendar calendar = Calendar.getInstance(); calendar.set(2021, 0, 31); System.out.println(calendar.getTime()); // 2021-1-31 calendar.add(Calendar.MONTH, 1); System.out.println(calendar.getTime()); // 2021-02-28 calendar.add(Calendar.MONTH, 15); System.out.println(calendar.getTime()); // 2022-05-28
roll(int field, int amount)
- 与add方法类似。区别在于,加上amount后超过了该字段所能表示的最大范围时,也不会向上一个字段进位。
- 下一级字段的处理规则与add方法相似
Calendar calendar = Calendar.getInstance(); calendar.set(2021, 0, 31); calendar.roll(Calendar.MONTH, 15); System.out.println(calendar.getTime()); // 2021-05-28设置Calendar的容错性
调用set()方法来改变指定时间字段的值时,有可能会传入一个不合法的参数,例如 MONTH超过11。
通过调用 setLenient(boolean lenient) 方法实现:
它用于设置容错性,Calendar默认支持较好的容错性。通过setLenient(false)来关闭容错性,让它进行严格的参数检查。当超过指定时间字段允许的取值范围时,程序会抛出异常。
set(int field, int value)
尽管字段field是立即修改的,但该Calenda所代表的时间却不会立即修改,直到调用 get()、getTime()、getTimeInMillis()、add() 、roll() 时,才会重新计算日历的时间,这被称为set()方法的延迟修改。
优势: 多次调用set()方法不会触发多次不必要的计算(计算一个代表实际时间的long型整数)。
Java8新增了一个 java.time的包。
同时也增加了一个 java.time.temporal 包,包括Temporal、TemporalAdjuster 等接口,下面的一些类都实现了这些接口,使用的时候注意下。
获取指定时区的当前日期、时间。
该类可取代System类的currentTimeMillis()方法,而且提供了更多方法获取日期、时间。
代表持续时间。可以方便的获取一段时间。
Instant代表一个具体的时刻,可以精确到纳秒。
LocalDate代表一个不带时区的日期。
案例:
LocalDate today = LocalDate.now(); // 获取本周周一和周日 LocalDate monday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); LocalDate sunday = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));LocalTime
代表一个不带时区的时间。
LocalDateTime代表一个不带时区的日期、时间。
MonthDay代表月日。
Year代表年。
YearMonth代表年月。
ZonedDateTime代表一个带时区的日期、时间
ZoneId代表一个时区
DayOfWeek枚举类,定义了周日到周六的枚举。
Month枚举类,定义了一月到十二月的枚举。
相关案例如下:
public static void main(String[] args) {
Clock clock = Clock.systemUTC();
System.out.println("当前时刻:" + clock.instant());
System.out.println(clock.getZone());
// 获取clock对应的毫秒数,和System.currentTimeMillis()输出相同
System.out.println(System.currentTimeMillis());
System.out.println(clock.millis());
Duration duration = Duration.ofSeconds(60100);
System.out.println(duration.toHours());
Instant instant = Instant.now();
System.out.println(instant);
System.out.println(instant.plusMillis(5));
LocalDate localDate = LocalDate.now();
System.out.println(localDate);
// 设置为某一天
System.out.println(LocalDate.of(2021, 1, 1));
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
Year year = Year.now();
System.out.println(year);
YearMonth yearMonth = YearMonth.now();
System.out.println(yearMonth);
MonthDay monthDay = MonthDay.now();
System.out.println(monthDay);
System.out.println(monthDay.withMonth(2).withDayOfMonth(4));
}
LocalDateTime、LocalDate、Date的相互转换
LocalDateTime 转 LocalDate
直接调用 toLocalDate() 方法
LocalDateTime localDateTime = LocalDateTime.now(); LocalDate localDate = localDateTime.toLocalDate();LocalDateTime 转 Date
在LocalDateTime 转 Date 时,需要使用到 Java 8的几个类
ZoneId/ZoneOffset:表示时区
ZonedDateTime: 表示特定时区的日期和时间
Instant:表示时刻,不直接对应年月日信息,需要通过时区转换
LocalDateTime localDateTime = LocalDateTime.now();
//获取系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
//时区的日期和时间
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
//获取时刻
Date date = Date.from(zonedDateTime.toInstant());
System.out.println("格式化前:localDateTime:" + localDateTime + " Date:" + date);
//格式化LocalDateTime、Date
DateTimeFormatter localDateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("格式化后:localDateTime:" + localDateTimeFormat.format(localDateTime) + " Date:" + dateFormat.format(date));
输出结果如下:
格式化前:localDateTime:2022-01-03T17:43:54.544 Date:Mon Jan 03 17:43:54 CST 2022 格式化后:localDateTime:2022-01-03 17:43:54 Date:2022-01-03 17:43:54LocalDate 转 LocalDateTime
一般调用 atTime() 方法进行赋值
LocalDate localDate = LocalDate.now(); LocalDateTime localDateTime1 = localDate.atStartOfDay(); LocalDateTime localDateTime2 = localDate.atTime(8,20,33); LocalDateTime localDateTime3 = localDate.atTime(LocalTime.now());LocalDate 转 Date
先调用 atStartOfDay() 方法转 LocalDateTime 再转 Date
LocalDate localDate = LocalDate.now(); ZoneId zoneId = ZoneId.systemDefault(); Date date = Date.from(localDate.atStartOfDay().atZone(zoneId).toInstant());Date 转 LocalDateTime
先转 ZonedDateTime 再转 LocalDateTime
Date date = new Date(); ZoneId zoneId = ZoneId.systemDefault(); LocalDateTime localDateTime = date.toInstant().atZone(zoneId).toLocalDateTime();Date 转 LocalDate
跟 LocalDate 同理
Date date = new Date(); ZoneId zoneId = ZoneId.systemDefault(); LocalDate localDate = date.toInstant().atZone(zoneId).toLocalDate();



