> 文档中心 > 还在实体类中用Date?JDK8新的日期类型不香么?

还在实体类中用Date?JDK8新的日期类型不香么?

今天想介绍的,就是我们再实体类中,很多时候会用到时间这个概念,比如说,记录的创建时间 CreateTime 或者说是某些需要确定的日期,在数据库存储的时候,毋庸置疑,肯定是 datetime 和 date 的数据类型,但是也有个别的比较过分,直接是用字符串,也就是varchar 来进行存储,而我们在之前是用 JDK7 的时候,我们创建时间的时候,很多时候都选择的时比较老版本的 Date、Calendar 以及 SimpleDateFormatter 等等。

不过 java.util.Date 也是被诟病已久,它包含了日期、时间、毫秒数等众多繁杂的信息,其内部利用午夜 12 点来区分日期,利用 1970-01-01 来计算时间;并且其月份从 0 开始计数,而且用于获得年、月、日等信息的接口也是太不直观。

除此之外,java.util.Date 与 SimpleDateFormatter 都不是类型安全的,

而我们接下来要使用的,就是 JDK8 中的日期,用来替换掉之前使用的。

JDK7 的日期 和 JDK8 的日期对比

JDK7 创建一个时间:

Date date = new Date();

JDK8 创建一个时间:

LocalDate today = LocalDate.now();

我们先看看这执行出来都是啥?

Date输出:Sun May 15 20:47:39 CST 2022
LocalDate输出:2022-05-15

首先我们从输出上,直接就感觉有点难受,Date输出的看起来就不是那么的直观,所以,当你想要直观的去输出这个时间的时候,可能就得用到 SimpleDateFormat 去格式化一下我们的这个时间。但是如果是用 LocalDate 就不会有这种顾虑了。

Date格式化:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");String str = sdf.format(date);

我们执行一下再看:

JDK7格式化后的时间数据 ==> 2022-05-15JDK8的时间数据 ==> 2022-05-15

首先,从代码上,就直接少了很多,毕竟转换时间相对来说是非常简单的。

这时候有的小伙伴可能会问,说如果我不想要这样的数据,那么我在 JDK8 里面怎么去转换这个时间呢?

我 JDK7 可以用 SimpleDateFormat,但是这个类并不支持我用 LocalDate 呀,别着急。既然人家敢出这个,那么肯定也得想到对应的方案。

JDK1.7 及之前版本我们使用 java.text.DataFormat 的子类(如 SimpleDateFormat 类)进行日期时间的格式化。

JDK1.8之后我们可以使用 java.time.format.DateTimeFormatter 来进行日期时间的格式化。

 LocalDate now = LocalDate.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); String JDK8Time = now.format(dateTimeFormatter); System.out.println("JDK8格式化后的时间数据 ==> " + JDK8Time);

我们看一下输出结果

JDK7格式化后的时间数据 ==> 2022/05/15JDK8格式化后的时间数据 ==> 2022/05/15

这属实没毛病是吧,但是,众所周知,SimpleDateFormat 是个线程不安全的,使用的时候,只能在方法内部创建新的局部变量。

而 DateTimeFormatter 不但是不变对象,它还是线程安全的。所以 DateTimeFormatter 可以只创建一个实例,到处引用。

这就是小编推荐大家换一下的原因,因为字符串转换时间的例子,用的地方实在是非常的多,我们在完成功能的同时,也需要尽量的保证自己代码的安全。

我们既然已经对比完成了,接下来就直接讲一下 JDK8 中的各种时间的用法。毕竟没有实战的空说,都是让人难以记忆的。

JDK8 日期的各种用法

String 转 LocalDate

LocalDate localDate = LocalDate.now();DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");String dateStr = localDate.format(fmt);System.out.println("LocalDate 转 String:" + dateStr);

转换结果:

LocalDateString2022/05/15

Date 转 LocalDate

System.out.println("LocalDateTime():" +  (new Date()).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());

转换结果:

LocalDateTime()2022-05-15T20:56:20.483

时间戳转 LocalDateTime

long timestamp = System.currentTimeMillis();Instant instant1 = Instant.ofEpochMilli(timestamp);System.out.println("时间戳转 LocalDateTime:" + LocalDateTime.ofInstant(instant1, ZoneId.systemDefault()));

转换结果:

时间戳转 LocalDateTime2022-05-15T20:58:20.537

下面是具体的一些 API:

API 方法 返回值 描述
getYear() int 获取当前日期的年份
getMonth() Month 获取当前日期的月份对象
getMonthValue() int 获取当前日期是第几月
getDayOfWeek() DayOfWeek 表示该对象表示的日期是星期几
getDayOfMonth() int 表示该对象表示的日期是这个月第几天
getDayOfYear() int 表示该对象表示的日期是今年第几天
withYear(int year) LocalDate 修改当前对象的年份
withMonth(int month) LocalDate 修改当前对象的月份
withDayOfMonth(intdayOfMonth) LocalDate 修改当前对象在当月的日期
isLeapYear() boolean 是否是闰年
lengthOfMonth() int 这个月有多少天
lengthOfYear() int 该对象表示的年份有多少天(365或者366)
plusYears(longyearsToAdd) LocalDate 当前对象增加指定的年份数
plusMonths(longmonthsToAdd) LocalDate 当前对象增加指定的月份数
plusWeeks(longweeksToAdd) LocalDate 当前对象增加指定的周数
plusDays(longdaysToAdd) LocalDate 当前对象增加指定的天数
minusYears(longyearsToSubtract) LocalDate 当前对象减去指定的年数
minusMonths(longmonthsToSubtract) LocalDate 当前对象减去指定的月数
minusWeeks(longweeksToSubtract) LocalDate 当前对象减去指定的周数
minusDays(longdaysToSubtract) LocalDate 当前对象减去指定的天数
compareTo(ChronoLocalDateother) int 比较当前对象和other对象在时间上的大小,返回值如果为正,则当前对象时间较晚
isBefore(ChronoLocalDateother) boolean 比较当前对象日期是否在other对象日期之前
isAfter(ChronoLocalDateother) boolean 比较当前对象日期是否在other对象日期之后
isEqual(ChronoLocalDateother) boolean 比较两个日期对象是否相等

以上的API相对来说已经是比较全面的,可以满足日常开发的需求了,如果是想看看结果的,大家不妨写个测试 Demo 去试试吧。

NICE