时间类有多复杂,JDK竟设计了三版
作者:鱼仔
博客首页: https://codeease.top
公众号:Java鱼仔
# (一)概述
时间类一直是代码开发中经常用到的东西,时间类在JDK中刚出现到国内最常用的1.8版本,一共迭代了三次。分别是Date类、Calendar类和LocalDateTime类。虽然JDK在更新,但是我看到很多的项目还是用着最初的Date类,这期就来讲一下三代时间类的区别。
# (二)Date类
Date类是JDK1.0时期推出来的第一代时间类,Date类最常用的方式是对获取当前时间,并使用SimpleDateFormat对时间进行格式化,代码如下:
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String stringDate = simpleDateFormat.format(date);
2
3
进入Date的构造函数方法中,可以发现目前还未弃用的是传入一个long类型的时间戳,获取到的是这个时间戳对应的Date对象
long timeStamp = 1652619436211L;
Date date = new Date(timeStamp);
2
另外Date还有一系列已经被废弃的API
如果强制想使用的话也可以用,但是获取当前年份需要+1900,获取当前月份需要+1
date.getYear()+1900
date.getMonth()+1
2
另外在使用SimpleDateFormat格式化Date类时还需要注意线程安全问题,因为SimpleDateFormat是线程不安全的,一般不要定义为static类型。
# (三)Calendar类
JDK1.1推出了Calendar类,用来代替Date类中得到年 月 日 小时等时间元素的api,Calendar提供了一系列获取时间元素的api,并且使用起来也比较简单,通过Calendar.getInstance()获取到Calendar对象,调用一系列API得到时间元素,代码如下:
Calendar calendar = Calendar.getInstance();
System.out.println("年:" + calendar.get(Calendar.YEAR));
// 初始月份是从0开始
System.out.println("月:" + (calendar.get(Calendar.MONTH)+1));
System.out.println("日:" + calendar.get(Calendar.DATE));
System.out.println("小时:" + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分钟:" + calendar.get(Calendar.MINUTE));
System.out.println("秒:" + calendar.get(Calendar.SECOND));
System.out.println("毫秒:" + calendar.get(Calendar.MILLISECOND));
System.out.println("今年的第几个星期:" + calendar.get(Calendar.WEEK_OF_YEAR));
System.out.println("这个月的第几个星期:" + calendar.get(Calendar.WEEK_OF_MONTH));
System.out.println("今年的第几天:" + calendar.get(Calendar.DAY_OF_YEAR));
System.out.println("这个月的第几天:" + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("这个星期的第几天:" + calendar.get(Calendar.DAY_OF_WEEK));
2
3
4
5
6
7
8
9
10
11
12
13
14
Calendar类的出现并没有替换掉Date类,它更像是对Date类的增强,Date可以作为Calendar设置时间的入参
calendar.setTime(new Date());
可能是Date类并不好用,所以出现了很多第三方的时间库,比如joda time。
# (四)LocalDateTime类
一直等到JDK1.8,JDK团队才对时间类做了一次大更新,有意思的是joda time的作者也一起参与了java.time这个包的设计中。这一版的时间类功能强大,并且解决了之前的问题。所以如果你的项目JDK是1.8及以上,可以大方地去使用java.time中提供的类。
java.time包中提供了四个常用的时间类,分别是Instant、LocalDate、LocalTime、LocalDateTime。
Instant中提供了一个更高精度的时间戳,LocalDate获取年-月-日,LocalTime获取时:分:秒.毫秒,LocalDateTime获取年-月-日T时:分:秒.毫秒。 下面介绍一下常见的使用方法:
Instant now = Instant.now();
//获取纳秒级别的时间戳
System.out.println(now.toEpochMilli());
LocalDate localDate=LocalDate.now();
LocalTime localTime=LocalTime.now();
LocalDateTime ldt = LocalDateTime.now();
System.out.println(localDate);
System.out.println(localTime);
System.out.println(ldt);
2
3
4
5
6
7
8
9
10
输出的结果如下:
1652621891272
2022-05-15
21:38:11.338
2022-05-15T21:38:11.338
2
3
4
时间格式化类也迎来了更新,DateTimeFormatter是一个线程安全的时间格式化类。
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dateTimeFormatter.format(ldt));
2
另外Calendar中的获取时间元素API,LocalDateTime也同样提供了
System.out.println(ldt.getYear());
System.out.println(ldt.getMonthValue());
System.out.println(ldt.getDayOfMonth());
System.out.println(ldt.getHour());
System.out.println(ldt.getMinute());
System.out.println(ldt.getSecond());
2
3
4
5
6
另外还提供了对时间的加减操作,比如加7天和减7天
LocalDateTime plusTime = ldt.plusDays(7);
LocalDateTime minusTime = ldt.minusDays(7);
System.out.println(plusTime);
System.out.println(minusTime);
2
3
4
# (五)数据库中的时间类型字段
在数据库中,时间类型有date、datetime、time、timestamp。很多人不知道在Java中如何去接收。我这边的建议是:
date类型使用LocalDate接收;
time类型使用LocalTime接收;
datetime类型使用LocalDateTime接收;
timestamp类型使用LocalDateTime接收;