JDK1.0版本(Date)
Date 类中的所有方法从 JDK1.1 开始便被弃用。
存在的问题:
- 计算差值时不准确、麻烦、设计反人类
- SimpleDateFormat 存在线程安全问题,即多线程环境下需要考虑并发问题
public class DateDemo {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
// 这里的设置就很反人类
calendar.set(2000, Calendar.JANUARY, 1);
long beginMill = calendar.getTimeInMillis();
Date date = new Date();
long endMill = date.getTime();
long days = (endMill - beginMill) / 1000 / 3600 / 24;
System.out.println("days = " + days);
long years = days / 365;
System.out.println("years = " + years);
}
}
JDK 8 版本(LocalDateTime)
注意:
- 出现过上面的结果和这里的结果存在一天之差?为什么?谁算错了?
- 但这种错误在几分钟后就消失了。大概是 2023-11-25 22:10:00 左右发生这种情况
在学习的视频演示案例中,也出现了这个问题,是 Date 类的问题
public class LocalDateDemo {
public static void main(String[] args) {
LocalDate begin = LocalDate.of(2000, 1, 1);
LocalDate end = LocalDate.now();
long days = ChronoUnit.DAYS.between(begin, end);
System.out.println("days = " + days);
long years = ChronoUnit.YEARS.between(begin, end);
System.out.println("years = " + years);
}
}
##时刻(时间点)
类 | 描述 |
---|---|
Instant | 1. 对时间轴上某个时刻的描述 2. 各种时间类型的转换媒介 |
LocalDate | |
LocalTime | |
LocalDateTime | |
ZonedDateTime |
共性:
java.time
包下的这些类都是 final 修饰的,final 修饰也表明对象是不可变的,因此解决线程安全问题。- 这些类属于工具类,设计者将构造器屏蔽掉,因此不能够使用
new
来创建对象,而是调用静态方法
of 方法:指定日期时间
public static void main(String[] args) {
// Duration和Period没有now()方法
Instant instant = Instant.now();
System.out.println("instant = " + instant);
LocalDate localDate = LocalDate.now();
System.out.println("localDate = " + localDate);
// 时分秒+纳秒,没有毫秒
LocalTime localTime = LocalTime.now();
System.out.println("localTime = " + localTime);
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime = " + localDateTime);
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println("zonedDateTime = " + zonedDateTime);
}
plus、minus 方法:增加/减少
public static void main(String[] args) {
// 处理了闰年等问题
LocalDateTime localDateTime1 = LocalDateTime.of(2000, 2, 28, 12, 0, 0);
LocalDateTime plusLocalDateTime1 = localDateTime1.plusWeeks(1);
System.out.println("plusLocalDateTime1 = " + plusLocalDateTime1);
LocalDateTime localDateTime2 = LocalDateTime.of(2001, 2, 28, 12, 0, 0);
LocalDateTime plusLocalDateTime2 = localDateTime2.plusWeeks(1);
System.out.println("plusLocalDateTime2 = " + plusLocalDateTime2);
// 采用链式编程来进行多次的计算
LocalDateTime ddl1 = LocalDateTime.now().plusYears(2).plusMonths(3).plusDays(8);
System.out.println("ddl1 = " + ddl1);
// 添加年月的逻辑是直接在对应属性上添加,然后避免越界
Period period = Period.of(1, 0, 0);
LocalDate ddl2 = LocalDate.of(2000, 2, 29).plus(period);
System.out.println("ddl2 = " + ddl2);//这里的结果是2001-02-28
}
时段(差值)
日期时间差值计算类 | 描述 |
---|---|
Duration | 用于计算 LocalTime 之间的差值 |
Period | 用于计算 LocalDate 之间的差值 |
public static void main(String[] args) {
// Period用于计算LocalDate之间的差值
LocalDate beginDate = LocalDate.of(2000, 1, 1);
LocalDate endDate = LocalDate.of(2023, 11, 25);
Period period = Period.between(beginDate, endDate);
System.out.println("period = " + period);
int days = period.getDays();
System.out.println("days = " + days);
// Duration用于计算LocalTime之间的差值
LocalTime beginTime = LocalTime.of(8, 53, 30);
LocalTime endTime = LocalTime.of(23, 12, 9);
Duration duration = Duration.between(beginTime, endTime);
System.out.println("duration = " + duration);
long minutes = duration.toMinutes();
System.out.println("minutes = " + minutes);
// Duration用于LocalDate会报错
}
时区
时区类 | 描述 |
---|---|
ZoneId | 时区信息 |
ZonedDateTime | 某个时区的 LocalDateTime |
既可以获取当前的时区,也可以进行不同时区的时间转换
public static void main(String[] args) {
// 所有的时区信息
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
zoneIds.forEach(System.out::println);
// 获取当前系统的默认时区
ZoneId defaultZoneId = ZoneId.systemDefault();
System.out.println("defaultZoneId = " + defaultZoneId);
System.out.println("====================================================");
// LocalDateTime:不包含时区信息。7点10分
LocalDateTime localDateTime = LocalDateTime.of(2023, 11, 25, 7, 10);
// ZonedDateTime:包含时区信息。
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println("zonedDateTime = " + zonedDateTime);
// 时区信息转换:上海的7点10分 != 洛杉矶的7点10分
ZonedDateTime otherZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("America/Los_Angeles"));
System.out.println("otherZonedDateTime = " + otherZonedDateTime);
// 转换成其它时区(二)
ZonedDateTime utcZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Etc/UTC"));
System.out.println("utcZonedDateTime = " + utcZonedDateTime);
}