51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

时间类有多复杂,JDK竟设计了三版

# (一)概述 {#一-概述}

时间类一直是代码开发中经常用到的东西,时间类在JDK中刚出现到国内最常用的1.8版本,一共迭代了三次。分别是Date类、Calendar类和LocalDateTime类。虽然JDK在更新,但是我看到很多的项目还是用着最初的Date类,这期就来讲一下三代时间类的区别。

# (二)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);

进入Date的构造函数方法中,可以发现目前还未弃用的是传入一个long类型的时间戳,获取到的是这个时间戳对应的Date对象

long timeStamp = 1652619436211L;
Date date = new Date(timeStamp);

另外Date还有一系列已经被废弃的API

如果强制想使用的话也可以用,但是获取当前年份需要+1900,获取当前月份需要+1

date.getYear()+1900
date.getMonth()+1

另外在使用SimpleDateFormat格式化Date类时还需要注意线程安全问题,因为SimpleDateFormat是线程不安全的,一般不要定义为static类型。

# (三)Calendar类 {#三-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));

Calendar类的出现并没有替换掉Date类,它更像是对Date类的增强,Date可以作为Calendar设置时间的入参

calendar.setTime(new Date());

可能是Date类并不好用,所以出现了很多第三方的时间库,比如joda time。

# (四)LocalDateTime类 {#四-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);

输出的结果如下:

1652621891272
2022-05-15
21:38:11.338
2022-05-15T21:38:11.338

时间格式化类也迎来了更新,DateTimeFormatter是一个线程安全的时间格式化类。

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dateTimeFormatter.format(ldt));

另外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());

另外还提供了对时间的加减操作,比如加7天和减7天

LocalDateTime plusTime = ldt.plusDays(7);
LocalDateTime minusTime = ldt.minusDays(7);
System.out.println(plusTime);
System.out.println(minusTime);

# (五)数据库中的时间类型字段 {#五-数据库中的时间类型字段}

在数据库中,时间类型有date、datetime、time、timestamp。很多人不知道在Java中如何去接收。我这边的建议是:

date类型使用LocalDate接收;

time类型使用LocalTime接收;

datetime类型使用LocalDateTime接收;

timestamp类型使用LocalDateTime接收;

赞(4)
未经允许不得转载:工具盒子 » 时间类有多复杂,JDK竟设计了三版