听说你还在用Date?

package com.ifilldream.rocketmq_lean.localdatatime_lean;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * @ClassName LocalDateTimeTest
 * @Description TODO
 * @Author RickSun && iFillDream
 * @Date 2020/1/11 10:13
 * @Version 1.0
 */
public class LocalDateTimeTest {

    /**
     提到Java的时间类,你一定想到的是Date,但是Date存在着一些不足之处
     Java8提供了新的时间类,那就是LocalDateTime。以前的Date不好用吗,为什么还要推出一个时间类?单纯从用法上看其实Date也不是特别复杂。
     但是Date最大的问题是线程不安全导致的一些列问题,很多方法都被官方标记为废弃,通常被废弃的方法都是要谨慎使用的。
     其次是Date的可读性非常差,为此Java8开始使用LocalDateTime替换之前的Date。
     */

    public static void main(String[] args) throws ParseException {
        //我们举几个例子(现在是2020年01月11日)
        showDate();
        showLocalDateTime();
        showOther();
    }

    /**
     * Date的用法
     */
    public static void showDate() throws ParseException {
        System.out.println("--------------Date---------------");
        Date dateNow = new Date();
        System.out.println("当前时间:" + dateNow);
        System.out.println("当前年份:" + dateNow.getYear());
        System.out.println("当前月份:" + dateNow.getMonth());
        System.out.printf("今年的第%tj%n",dateNow);
        System.out.printf("本月的第%td%n",dateNow);
        String dayOfWeek = new SimpleDateFormat("E").format(dateNow);
        System.out.println(dayOfWeek);

        //构造时间
        Date consDate  = new  Date(2020,01,11,14,14,00);
        System.out.println("构造:" + consDate);

        //日期的加减
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateNow);
        calendar.add(Calendar.DATE, 1);
        calendar.add(Calendar.HOUR, 2);
        calendar.add(Calendar.MINUTE,3);

        calendar.add(Calendar.DATE, -1);
        calendar.add(Calendar.HOUR, -2);
        calendar.add(Calendar.MINUTE,-3);
        System.out.println("加减时间:" + calendar.getTime());

        //修改指定日期
        calendar.set(Calendar.DAY_OF_MONTH,20);
        Date withDayOfMonth = calendar.getTime();
        System.out.println("修改日期:" + withDayOfMonth);
        calendar.set(Calendar.DAY_OF_YEAR,100);
        Date withDayOfYear = calendar.getTime();
        System.out.println("修改日期:" + withDayOfYear);

        //时间比较
        boolean compareBefore = withDayOfMonth.before(withDayOfYear);
        boolean compareAfter = withDayOfMonth.after(withDayOfYear);
        boolean compareEqual = withDayOfMonth.getTime() == withDayOfYear.getTime();
        System.out.println("比较是否小于 : " + compareBefore);
        System.out.println("比较是否大于 : " + compareAfter);
        System.out.println("比较是否等于: " + compareEqual);

        //字符串转时间
        String datetime =  "2017-11-23 06:08:09";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //SimpleDateFormat是线程不安全的
        Date changeTime = sdf.parse(datetime); //此处还要抛异常
        System.out.println("字符串转时间: " + changeTime);

        //时间转字符串
        System.out.println("时间转字符串1: " + sdf.format(changeTime));

        //毫秒转时间
        System.out.println("毫秒转时间:" + new Date(System.currentTimeMillis()));

        //两个时间间隔
        //具体代码就不放上来了
        //参考https://blog.csdn.net/zpz2411232428/article/details/83278931
        /**
         实现1949-10-1  ---  2016-8-15 之间的天数。
             方法一:
                 通过Calendar类的日期比较
                 1,日期是跨年份的
                 2,年份有闰年和平年
                思路:
                 1,通过SimpleDateFormat初始化时间时刻
                 2,Date对象的方法大多过时,我们用Calendar类来计算
                 3,Calendar中的get方法可以获取各个字段的值,例如:DAY_OF_YEAR 一年里当前年时刻的天数
                 4,计算两个年份之间相差多少年
                 5,判断平年还是闰年 平年加366天  闰年加365天
                 6,年份的天数加上当前年时刻天数的差得到结果。
            方法二:
                Date类的gettime方法返回当前对象一个long值 (单位毫秒)
                 思路:
                 1,分别计算两个对象的long值。
                 2,再用long值想减。
                 3,用相减的毫秒换算成天数。
         */
    }

    /**
     * LocalDateTime的用法
     */
    public static void showLocalDateTime(){
        System.out.println("--------------LocalDateTime---------------");
        LocalDateTime localNow = LocalDateTime.now();
        System.out.println("当前时间:" + localNow);
        System.out.println("当前年份:" + localNow.getYear() );
        System.out.println("当前月份:" + localNow.getMonth());
        int dayOfYear = localNow.getDayOfYear();
        int dayOfMonth = localNow.getDayOfMonth();
        DayOfWeek dayOfWeek = localNow.getDayOfWeek();
        System.out.println("LocalDateTime今年的第" + dayOfYear + "天");
        System.out.println("LocalDateTime本月的第" + dayOfMonth + "天");
        System.out.println("LocalDateTime星期" + dayOfWeek.getValue() + "(" + dayOfWeek + ")");

        //构造时间
        LocalDateTime consLocal = LocalDateTime.of(2020,01,11,14,14,00);
        System.out.println("LocalDateTime构造:" + consLocal);

        //日期的加减
        localNow.plusDays(1);
        localNow.plusHours(2);
        localNow.plusMinutes(3);

        localNow.minusDays(1);
        localNow.minusHours(2);
        localNow.minusMinutes(3);
        System.out.println("LocalDateTime加减时间:" + localNow);

        //修改指定日期
        LocalDateTime withDayOfMonth = localNow.withDayOfMonth(20);
        LocalDateTime withDayOfYear = localNow.withDayOfYear(100);
        System.out.println("LocalDateTime修改日期:" + withDayOfMonth);
        System.out.println("LocalDateTime修改日期:" + withDayOfYear);

        //时间比较
        boolean compareBefore = withDayOfMonth.isBefore(withDayOfYear);
        boolean compareAfter = withDayOfMonth.isAfter(withDayOfYear);
        boolean compareEqual = withDayOfMonth.isEqual(withDayOfYear);
        System.out.println("LocalDateTime比较是否小于 : " + compareBefore);
        System.out.println("LocalDateTime比较是否大于 : " + compareAfter);
        System.out.println("LocalDateTime比较是否等于: " + compareEqual);

        //字符串转时间
        String datetime =  "2017-11-23 06:08:09";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime changeTime = LocalDateTime.parse(datetime, dtf);
        System.out.println("LocalDateTime字符串转时间: " + changeTime);

        //时间转字符串
        System.out.println("LocalDateTime时间转字符串1: " +dtf.format(changeTime));
        System.out.println("LocalDateTime时间转字符串2: " + localNow.format(DateTimeFormatter.BASIC_ISO_DATE) );
        System.out.println("LocalDateTime时间转字符串3: " + localNow.format(DateTimeFormatter.ISO_DATE) );

        //毫秒转时间
        String longToDateTime = dtf.format(LocalDateTime.ofInstant(
                Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.of("Asia/Shanghai")));
        System.out.println("LocalDateTime毫秒转时间:" + longToDateTime);

        //两个时间间隔
        Duration between = Duration.between(withDayOfMonth, withDayOfYear);
        System.out.println("时间间隔:" + between.toDays());
        System.out.println("时间间隔:" + between.toHours());

    }

    public static void showOther(){
        System.out.println("--------------LocalDate&LocalTime---------------");
        LocalDate localDate = LocalDate.of(2017, 11, 23);
        System.out.println("构造LocalDate:" + localDate);
        LocalTime localTime = LocalTime.of(8, 6, 00);
        System.out.println("构造LocalTime:" + localTime);

        LocalDate today = LocalDate.now();
        System.out.println("是否闰年:" + today.isLeapYear());

        //将年、月、日等修改为指定的值,并返回新的日期与LocalDateTime一样此处不再赘述
        //两个日期前后判断与LocalDateTime一致

        System.out.println("获取时间的纳秒:" + localTime.getNano());

       //程序运行时间
        Instant startTime = Instant.now();
        //TODO do someting
        Instant endTime = Instant.now();
        Duration duration = Duration.between(startTime, endTime);
        System.out.println("程序运行:" + duration.toMillis() + "毫秒");
    }
}

运行效果如下:


file

file

可以看得出来LocalDateTime具有非常多的优势。
通过源码我们可以看出SimpleDateFormat也是不安全的,然而Date用到SimpleDateFormat的地方非常多,同时Date也是不安全的。


file

通过源码可以看出LocalDateTime是线程安全的。
file

统一首发平台为微信公众号"轻梦致新",搜索关注公众号,第一时间阅读最新内容。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容