LocalDateTime就应该代替Date

本文深入对比Java8前的Date类与新的LocalDateTime类,详细解析LocalDateTime的构造、使用、线程安全特性及如何替代旧版时间处理方式。

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

一、起源:

 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)

 

方法摘要
 intgetHours()
          已过时。  
 intgetMinutes()
          已过时。  
 intgetSeconds()
          已过时。  
 voidsetHours(int i)
          已过时。  
 voidsetMinutes(int i)
          已过时。  
 voidsetSeconds(int i)
          已过时。  
 voidsetTime(long date)
          使用给定毫秒时间值设置现有 Date 对象。
 StringtoString()
          格式化日期转义形式 yyyy-mm-dd 的日期。
static DatevalueOf(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 程序羊文章,若有侵权,请联系改正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真香号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值