
日期常用操作
我们对日期的常用操作无非三种:
日期的表示,日期的转换,日期的修改
对于日期的表示我们原来通常使用的是Date类。
对于日期的转换我们使用的是DateFormat,比如把date对象转换成字符串,或者把相应的字符串转换成date对象。
但是,我要告诉大家,请把这些统统丢掉,下面我会给大家说为什么。
Date
首先看一下Date类,如果大家用的是1.8或者之后的版本,Date类是不建议大家使用的。至于为什么,我们看一下这个类的方法,大部分都已经遗弃了。

你看,连官方都已经放弃了,谁用谁遭罪,真的。
那么为什么连官方都放弃了呢?
我们首先看一下他的无参构造方法,很简单,就一行。
public Date(){
this(System.currentTimeMillis());
}
那我们按照他的写法来new一个对象使用一下。
Date date = new Date();
System.out.println("当前时间"+date);
System.out.println("年份"+date.getYear());
System.out.println("月份"+date.getMonth());
输出结果:

不明白的人一看年份是120?什么玩意?月份明明是2月,到这里成了1月,哪家公司要是直接给客户看这个,客户能选这家公司才奇了怪了。
而且,Date对象如果没有经过格式化,得到的结果可读性太差,要是谁敢把结果直接放到输出显示上,估计离凉凉也就不远了。
对于Date而言,通常使用SimpleDateFormat进行格式化,即日期的转换。
SimpleDateFormat
那我们可以看一下他的源码,看看他到底好不好。

源码上显示,这个类他是线程不安全的,下面是其format代码,如果不想深究的可以直接看下面LocalDateTime类。
private StringBuffer format(Date date, StringBuffer toAppendTo,
FieldDelegate delegate) {
// Convert input date to time field list
calendar.setTime(date);
boolean useDateFormatSymbols = useDateFormatSymbols();
for (int i = 0; i < compiledPattern.length; ) {
int tag = compiledPattern[i] >>> 8;
int count = compiledPattern[i++] & 0xff;
if (count == 255) {
count = compiledPattern[i++] << 16;
count |= compiledPattern[i++];
}
switch (tag) {
case TAG_QUOTE_ASCII_CHAR:
toAppendTo.append((char)count);
break;
case TAG_QUOTE_CHARS:
toAppendTo.append(compiledPattern, i, count);
i += count;
break;
default:
subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
break;
}
}
return toAppendTo;
}
并发有几个点是很重要的,共享和可变,在上面代码段中有一个变量是calendar,这是一个共享变量,并且他包含了读改写三个操作,违背了原子性的原则,当多个线程同时调用该方法的时候,该变量的值会返回错误的值。
对并发感兴趣的看《Java并发编程实战》。
当然,一个落后的总是被先进的替代,这就是我们接下来要说的LocalDateTime。
LocalDateTime
LocalDateTime是Java8新提供的类,他可以提供年月日时分秒,等同于LocalDate(只会获取年月日)+LocalTime(获取时分秒)。
从源码可以看出,这是一个线程安全的类。

我们尝试使用一下试试。

LocalDateTime nowTime = LocalDateTime.now();
System.out.println("当前时间:" + nowTime + "," + "当前年份:" + nowTime.getYear() + "," + "当前月份:" + nowTime.getMonth());
输出结果:

这样一看是不是就正常多了。但是为了美观易懂,我们还需要格式化一下,与LocalDateTime对应的格式化是DateTimeFormatter。
DateTimeFormatter
DateTimeFormatter默认提供了很多种格式化的方法,如:
String s1 = nowTime.format(DateTimeFormatter.BASIC_ISO_DATE);
String s1 = nowTime.format(DateTimeFormatter.ISO_LOCAL_DATE);
但其实大家更常用的是自定义的,比如下面这样:
String thisYear = nowTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
输出结果:

关键在于,他是线程安全的,所以我们就不必在并发的时候给其加锁了。
所以,大家以后遇到处理日期的问题时,只需要记住LocalDateTime以DateTimeFormatter就可以了。
关于日期的操作就说到这里,对于日期的其他操作只需要进去类里面看一看就可以了。如果大家有什么疑问,欢迎下方留言。
谢谢观看。