转换date_我们为什么对Date类喜新厌旧?

博客介绍了Java中日期的常用操作,包括表示、转换和修改。指出旧的Date类和SimpleDateFormat存在问题,如Date类很多方法被弃用、输出可读性差,SimpleDateFormat线程不安全。推荐使用Java 8新提供的LocalDateTime和DateTimeFormatter,它们线程安全,能更好地处理日期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bde8f3e1ebe37485de6ebd5576a1392c.png

日期常用操作

我们对日期的常用操作无非三种:

日期的表示,日期的转换,日期的修改

对于日期的表示我们原来通常使用的是Date类。

对于日期的转换我们使用的是DateFormat,比如把date对象转换成字符串,或者把相应的字符串转换成date对象。

但是,我要告诉大家,请把这些统统丢掉,下面我会给大家说为什么。

Date

首先看一下Date类,如果大家用的是1.8或者之后的版本,Date类是不建议大家使用的。至于为什么,我们看一下这个类的方法,大部分都已经遗弃了。

87dcf32d398b4878e5d5e902c4ffc580.png

你看,连官方都已经放弃了,谁用谁遭罪,真的。

那么为什么连官方都放弃了呢?

我们首先看一下他的无参构造方法,很简单,就一行。

public Date(){
    this(System.currentTimeMillis());
}

那我们按照他的写法来new一个对象使用一下。

Date date = new Date();
System.out.println("当前时间"+date);
System.out.println("年份"+date.getYear());
System.out.println("月份"+date.getMonth());

输出结果:

8d4492781bdd3c1343da018b9d395ebe.png

不明白的人一看年份是120?什么玩意?月份明明是2月,到这里成了1月,哪家公司要是直接给客户看这个,客户能选这家公司才奇了怪了。

而且,Date对象如果没有经过格式化,得到的结果可读性太差,要是谁敢把结果直接放到输出显示上,估计离凉凉也就不远了。

对于Date而言,通常使用SimpleDateFormat进行格式化,即日期的转换。

SimpleDateFormat

那我们可以看一下他的源码,看看他到底好不好。

8ae2e56b301aa1fba1b6eb79b093e3db.png

源码上显示,这个类他是线程不安全的,下面是其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(获取时分秒)。

从源码可以看出,这是一个线程安全的类。

cb30869321070404b5178ae49ae9a1c2.png

我们尝试使用一下试试。

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

输出结果:

eb976bd1b60c9ef1e76df701e4e3082d.png

这样一看是不是就正常多了。但是为了美观易懂,我们还需要格式化一下,与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"));

输出结果:

f076a702c501d2c0f65c6b316f86621a.png

关键在于,他是线程安全的,所以我们就不必在并发的时候给其加锁了。

所以,大家以后遇到处理日期的问题时,只需要记住LocalDateTime以DateTimeFormatter就可以了。

关于日期的操作就说到这里,对于日期的其他操作只需要进去类里面看一看就可以了。如果大家有什么疑问,欢迎下方留言。

谢谢观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值