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

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

(一)概述

时间类一直是代码开发中经常用到的东西,时间类在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);

进入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类

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类

一直等到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接收;

相关文章
|
7月前
|
安全 Java API
JDK 11中的动态类文件常量:探索Java字节码的灵活性与动态性
在JDK 11中,Java语言引入了一个新的特性,允许在运行时动态地修改类文件常量。这一特性为Java开发者提供了更大的灵活性,使他们能够根据需要在运行时更改类文件中的常量值。本文将深入探讨动态类文件常量的工作原理、优点、限制以及在实际项目中的应用。
162 11
|
7月前
|
安全 Java API
14.JDK底层Unsafe类是个啥东西?
14.JDK底层Unsafe类是个啥东西?
83 0
14.JDK底层Unsafe类是个啥东西?
|
7月前
|
Java
Integer类【JDK源码分析】
Integer类【JDK源码分析】
52 0
|
3月前
|
Java Linux
java基础(3)安装好JDK后使用javac.exe编译java文件、java.exe运行编译好的类
本文介绍了如何在安装JDK后使用`javac.exe`编译Java文件,以及使用`java.exe`运行编译好的类文件。涵盖了JDK的安装、环境变量配置、编写Java程序、使用命令行编译和运行程序的步骤,并提供了解决中文乱码的方法。
77 2
|
Java
Java之JDK8时间相关类的详细解析
Java之JDK8时间相关类的详细解析
82 0
|
3月前
|
Java API 开发者
【Java字节码操控新篇章】JDK 22类文件API预览:解锁Java底层的无限可能!
【9月更文挑战第6天】JDK 22的类文件API为Java开发者们打开了一扇通往Java底层世界的大门。通过这个API,我们可以更加深入地理解Java程序的工作原理,实现更加灵活和强大的功能。虽然目前它还处于预览版阶段,但我们已经可以预见其在未来Java开发中的重要地位。让我们共同期待Java字节码操控新篇章的到来!
|
3月前
|
Java API 开发者
【Java字节码的掌控者】JDK 22类文件API:解锁Java深层次的奥秘,赋能开发者无限可能!
【9月更文挑战第8天】JDK 22类文件API的引入,为Java开发者们打开了一扇通往Java字节码操控新世界的大门。通过这个API,我们可以更加深入地理解Java程序的底层行为,实现更加高效、可靠和创新的Java应用。虽然目前它还处于预览版阶段,但我们已经可以预见其在未来Java开发中的重要地位。让我们共同期待Java字节码操控新篇章的到来,并积极探索类文件API带来的无限可能!
|
4月前
|
存储 Java
【Java集合类面试七】、 JDK7和JDK8中的HashMap有什么区别?
JDK7中的HashMap使用数组加链表解决冲突,而JDK8增加了红黑树结构以优化链表过长时的性能,提高查找效率。
|
4月前
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
|
4月前
|
Java 编译器 API
JDK版本特性问题之在 JDK 17 中,想声明一个密封类,如何解决
JDK版本特性问题之在 JDK 17 中,想声明一个密封类,如何解决