一、起源:
LocalDateTime:自 Java8
开始, JDK
中其实就增加了一系列表示日期和时间的新类,最典型的就是 LocalDateTime
。直言不讳,这玩意的出现就是为了干掉之前 JDK
版本中的 Date
老哥!
-
LocalDateTime
是一个不可变的日期时间对象,代表日期时间,通常被视为年 - 月 - 日 - 时 - 分 - 秒。 也可以访问其他日期和时间字段,例如日期,星期几和星期。 时间表示为纳秒精度。 例如,值“2007年10月2日在13:45.30.123456789”可以存储在LocalDateTime
。 -
不可变:代表线程安全
二、缺点
先看看旧版的Date
//先看看旧版的Date
Date rightNow =new Date();
System.out.println("当前时间"+rightNow);
System.out.println("当前年份"+rightNow.getYear());
System.out.println("当前月份"+rightNow.getMonth());
输出:
当前时间Mon Dec 30 21:29:00 CST 2019
当前年份119
当前月份11第一行:显示时刻,可读性差
第二行:我希望返回的是年,今年是2019年,你返回119,读不懂。
第三行:当前月份是12月,返回的是11。不是很懂啊
二、构造函数、方法大多都被弃用
-
-
Date()
分配一个
Date
对象,并初始化它,以便它代表它被分配的时间,测量到最近的毫秒。Date(int year, int month, int date)
已弃用截至JDK 1.1版,由
Calendar.set(year + 1900, month, date)
或GregorianCalendar(year + 1900, month, date)
。Date(int year, int month, int date, int hrs, int min)
已弃用从JDK 1.1版开始,替换为
Calendar.set(year + 1900, month, date, hrs, min)
或GregorianCalendar(year + 1900, month, date, hrs, min)
。Date(int year, int month, int date, int hrs, int min, int sec)
已弃用截至JDK 1.1版,由
Calendar.set(year + 1900, month, date, hrs, min, sec)
或GregorianCalendar(year + 1900, month, date, hrs, min, sec)
。Date(long date)
分配一个
Date
对象,并将其初始化为表示自称为“时代”的标准基准时间以后的指定毫秒数,即1970年1月1日00:00:00 GMT。Date(String s)
已弃用从JDK 1.1版开始,由
DateFormat.parse(String s)
。
-
方法摘要 | |
---|---|
int | getHours() 已过时。 |
int | getMinutes() 已过时。 |
int | getSeconds() 已过时。 |
void | setHours(int i) 已过时。 |
void | setMinutes(int i) 已过时。 |
void | setSeconds(int i) 已过时。 |
void | setTime(long date) 使用给定毫秒时间值设置现有 Date 对象。 |
String | toString() 格式化日期转义形式 yyyy-mm-dd 的日期。 |
static Date | valueOf(String s) 将 JDBC 日期转义形式的字符串转换成 Date 值。 |
三、如果我们需要获取一个指定输出格式的时间日期,还需要设置样式,或者利用SimpleDateFormat去构造。这样实在是太麻烦了。
接下来看LocalDateTime
同样演示:
LocalDateTime rightNow = LocalDateTime.now();
System.out.println("当前时间"+rightNow);
System.out.println("当前年份"+rightNow.getYear());
System.out.println("当前月份"+rightNow.getMonth());
System.out.println("当前日期"+rightNow.getDayOfMonth());
System.out.println("当前时"+rightNow.getHour());
System.out.println("当前分"+rightNow.getMinute());
System.out.println("当前秒"+rightNow.getSecond());
输出:
当前时间2019-12-30T21:43:10.428
当前年份2019
当前月份DECEMBER
当前日期30
当前时21
当前分43
当前秒10
四、构造一个指定的时间日期:
比如:2019年10月30日12时45分12秒
LocalDateTime conTime= LocalDateTime.of(2019,10,30,12,45,12);
五、修改日期:
LocalDateTime rightNow = LocalDateTime.now();
//减少两年
rightNow = rightNow.minusYears(2);
//增加3个月
rightNow = rightNow.plusMonths(3);
//直接修改年份为2009
rightNow = rightNow.withYear(2009);
//修改小时直接到13时
rightNow = rightNow.withHour(13);
六、格式化日期:
//格式化时间日期
String num1 = rightNow.format(DateTimeFormatter.ISO_DATE);
String num2 = rightNow.format(DateTimeFormatter.BASIC_ISO_DATE);
String num3 = rightNow.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
System.out.println("格式化后的日期(格式一)"+num1);
System.out.println("格式化后的日期(格式二)"+num2);
System.out.println("格式化后的日期(格式三)"+num3);
输出结果:
格式化后的日期(格式一)2009-03-30
格式化后的日期(格式二)20090330
格式化后的日期(格式三)2009/03/30
七、字符串转成时间
LocalDateTime time =LocalDateTime.parse("2018--07--18 13:42:15",DateTimeFormatter.ofPattern("yyyy--MM--dd HH:mm:ss"));
System.out.println("解析后的时间为:"+time);
解析后的时间为:2018-07-18T13:42:15
八、线程安全问题
其实上面讲来讲去只讲了两者在用法上的差别,这其实倒还好,并不致命,可是接下来要讨论的线程安全性问题才是致命的!
其实以前我们惯用的 Date
时间类是可变类,这就意味着在多线程环境下对共享 Date
变量进行操作时,必须由程序员自己来保证线程安全!否则极有可能翻车。
而自 Java8
开始推出的 LocalDateTime
却是线程安全的,开发人员不用再考虑并发问题,这点我们从 LocalDateTime
的官方源码中即可看出:
This class is immutable and thread-safe:这个类是不可变的和线程安全的
大家除了惯用 Date
来表示时间之外,还有一个用于和 Date
连用的 SimpleDateFormat
时间格式化类大家可能也戒不掉了!
SimpleDateFormat
最主要的致命问题也是在于它本身并不线程安全,这在它的源码注释里已然告知过了:
那取而代之,我们现在改用什么呢?其实在前文已经用到啦,那就是了 DateTimeFormatter
了,他也是线程安全的:
如果改用了LocalDateTime 那么数据库中对应的类型应改为timestamp。
文章有部分参考公众号CodeSheep 程序羊文章,若有侵权,请联系改正。