自 Java8开始以来, JDK新增加了一系列表示日期和时间的新类,最典型的就是 LocalDateTime。而这个类就是官方为了取代旧版的时间类Date而添加的,现如今Date类的大部分方法都已被官方所弃用。如果你还是一个与时俱进的优秀开发人员,那么还继续使用Date类的你就显得有点跟不是潮流了。
Date类
获取当前时间
Date nowTime = new Date();
System.out.println("当前时间: " + nowTime);
System.out.println("当前年份: " + nowTime.getYear());
System.out.println("当前月份: " + nowTime.getMonth());
//当前时间: Wed Jan 01 17:16:42 CST 2020
//当前年份: 120
//当前月份: 0
打印的第二、第三行与一般常识都有偏差,显然不适合使用
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());
//当前时间: 2020-01-01T20:26:55.666
//当前年份: 2020
//当前月份: JANUARY
//当前日份: 1
//当前时分: 20
//当前分: 26
//当前秒: 55
二、构造一个指定年、月、日的时间:
比如,想构造:2019年11月11月11日11时11分11秒
LocalDateTime beforeDate = LocalDateTime.of(2019, Month.NOVEMBER,11,11,11,11);
System.out.println("构造一个时间: " + beforeDate);
//构造一个时间: 2019-11-11T11:11:11
三、修改日期
System.out.println("减少2年: " + beforeDate.minusYears(2));
System.out.println("增加3个月: " + beforeDate.plusMonths(3));
System.out.println("修改年份: " + beforeDate.withYear(2011));
System.out.println("修改时: " + beforeDate.withHour(21));
//减少2年: 2017-11-11T11:11:11
//增加3个月: 2020-02-11T11:11:11
//修改年份: 2011-11-11T11:11:11
//修改时: 2019-11-11T21:11:11
四、日期格式化
LocalDateTime testDate = LocalDateTime.of(2019, Month.NOVEMBER, 11, 11, 11, 11);
String result1 = testDate.format(DateTimeFormatter.ISO_DATE);
String result2 = testDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String result3 = testDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
System.out.println("基本样式一: " + result1);
System.out.println("基本样式二: " + result2);
System.out.println("自定义样式: " + result3);
//基本样式一: 2019-11-11
//基本样式二: 20191111
//自定义样式: 2019/11/11
五、时间反解析
LocalDateTime testTime = LocalDateTime.parse("2002--02--02 22:22",DateTimeFormatter.ofPattern("yyyy--MM--dd HH:mm"));
System.out.println("字符串反解析后的时间为: " + testTime);
//字符串反解析后的时间为: 2002-02-02T22:22
线程安全问题
一、Date类和LocalDateTime类的线程安全性
Date类和LocalDateTime类在用法上没有什么颠覆性的差别,这并不是什么重大到需要放弃使用的问题。而真正致命的则是他们之间的线程安全性问题!
我们一直在用的Date时间类是可变类,这就意味着在多线程环境下对共享 Date变量进行操作时,必须由程序员自己来保证线程安全!否则极有可能翻车。
而自 Java8开始推出的 LocalDateTime却是线程安全的,开发人员不用再考虑并发问题,这点我们从 LocalDateTime的官方源码中即可看出:
##########################################################################
# This class is immutable and thread-safe.(谷歌友情翻译:此类是不可变的并且是线程安全的。)
###########################################################################
二、日期格式化的选择和线程安全
除了使用 Date 来表示时间之外,还有一个用于和 Date 连用的 SimpleDateFormat 时间格式化类。SimpleDateFormat 最主要的致命问题也是在于它本身并不线程安全,这在它的源码注释里已然告知过了。而取而代之的,就是在前面所用到的 DateTimeFormatter 了,它跟 LocalDateTime 同样也是线程安全的。
##########################################################################
# This class is immutable and thread-safe.(谷歌友情翻译:此类是不可变的并且是线程安全的。)
###########################################################################