• Java日期时间的前世今生


    🙉 作者简介: 全栈领域新星创作者 ;天天被业务折腾得死去活来的同时依然保有对各项技术热忱的追求,把分享变成一种习惯,再小的帆也能远航。

    🏡 个人主页:xiezhr的个人主页

    前言

    日常开发中,日期和时间是我们经常遇到并且需要处理的。由于日期时间的复杂性,随着Java的发展,也诞生了三代日期处理API。接下来就让我们一起来探究下Java日期时间的前世今生。

    一、基本概念

    1.1 日期与时间

    日期是指某一天,它不是连续变化的;而时间分为带日期的时间和不带日期的时间
    带日期的时间能唯一确定某个时刻,不带日期的时间是无法确定一个唯一时刻的

    日期如下

    • 2022-05-20
    • 1992-09-13

    时间如下

    • 2022-11-20 08:01:59
    • 08:01:59
    1.2 本地时间

    当前时刻是2022年11月20日早上8:08,我们实际上说的是本地时间,也就是北京时间。
    在这里插入图片描述
    有点常识的我们都知道,如果这一个时间点,地球是不同地区的小伙伴看手表,看到的本地时间是不同的。
    在这里插入图片描述
    不同的时区,在同一时刻,本地时间是不同的。

    1.3 时区

    由于本地时间没法确定一个准确时刻,所以时区的概念就出现了
    全球一共分为24个时区伦敦所在的时区称为标准时区
    其他时区按东/西偏移的小时区分,北京所在的时区是东八区

    时区的三种表示方式

    • 以GMT或者UTC加时区偏移表示

    GMT是前世界标准时,UTC是现世界标准时,UTC 比 GMT更精准,以原子时计时,每隔几年会有一个闰秒,我们在开发程序的时候可以忽略两者的误差

    例如:GMT+08:00或者UTC+08:00 表示东八区 UTC/GMT +9:00 表示东九区

    • 以缩写表示
      例如:CST表示China Standard Time,也就是中国标准时间
    • 以洲/城市表示
      例如:Asia/Shanghai,表示上海所在地的时区。城市名称不是任意的城市,而是由国际标准组织规定的城市。

    这里好学的小伙伴就会问了,中国的时区为什么是Asia/Shanghai,而不是Asia/Beijing 呢?
    北京和上海处于同一时区(东八区),只能保留一个。而作为时区代表上海已经足够具有代表性。
    东八区

    **注:**虽然身处不同时区的两个小伙伴,同一时刻表上显示的本地时间不同,但两个表示的时刻是相同的

    1.4 夏令时

    是夏天开始的时候,把时间往后拨1小时,夏天结束的时候,再把时间往前拨1小时

    夏令时是比时区更为复杂的计算方式,很多地区都是不执行夏令时的,我国也在1992年就废除了
    在这里插入图片描述
    在这里插入图片描述

    二、Java三代日期时间API

    • 第一代日期时间类定义在java.util包下,主要包含DateSimpleDateFormat
    • 第二代日期时间类也是定义在java.util包下,主要是CalendarTimeZone
    • 第三代日期时间类是在Java 8引入的,定义在java.time 包下,主要包含LocalDateTimeZonedDateTimeZoneIdDateTimeFormatter

    此时,小伙伴可能会问了

    为什么会出现三代日期时间类呢?
    答:历史遗留问题,早期的API存在着很多问题,所以java在不断迭代更新,引入了新的API。更加方便我们处理日期时间

    既然早期API存在诸多问题,我们能不能直接使用最新API呢?

    答:如果是新项目,就建议使用最新API。因为新的API中的类是不变对象,并且是线程安全的;
    如果读者和我一样苦逼,还得维护JDK1.6 这样的遗留代码,就必须对一二代API有所了解。

    如果要维护历史遗留代码,新旧API可以相互转换吗?
    答:当然了,新旧API之间也是可以相互转换的。

    三、 第一代日期时间Date

    3.1 继承关系

    在这里插入图片描述

    3.2 获取实例对象

    在这里插入图片描述
    从上图可以看出,已经弃用了好多。这里我们说一说常用的两种

    • Date()
      创建的对象可以获取本地当前时间,精确到毫秒
      -Date(long date)
      以从1970 年 1 月 1 日 0 时 0 分 0 秒 开始的毫秒数初始化时间对象
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) {
            Date date1 = new Date();
            System.out.println(date1);
            Date date2 = new Date(15000);
            System.out.println(date2);
          
        }
    }
    //输出
    Sun Nov 20 09:55:58 CST 2022
    Thu Jan 01 08:00:15 CST 1970
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    3.3 常用方法

    在这里插入图片描述
    我们发现好多也是已弃用了,这里面的很多方法将会被第二代日期时间中的方法取代

    3.3 获取当前年月日时分秒

    getYear()getMonth()date.getDate()getHours()getMinutes()getSeconds()
    toString()toGMTString()toLocaleString()

    注:

    • getYear()返回的年份必须加上1900
    • getMonth() 返回的月份是0-11 分别表示1-12月,所以要+1
    • getDate() 返回的日期范围是1~31,不能加1
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) {
            //获取当前时间
            Date date = new Date();
            //获取当前年份
            System.out.println((date.getYear() + 1900));
            //获取当前月份
            System.out.println((date.getMonth() + 1));
            //获取当前日
            System.out.println(date.getDate());
            //获取小时
            System.out.println(date.getHours());
            //获取分钟
            System.out.println(date.getMinutes());
            //获取秒
            System.out.println(date.getSeconds());
        }
    }
    //输出
    2022
    11
    20
    10
    17
    1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    3.4 日期时间转换

    toString()toGMTString()toLocaleString()

    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) {
            //获取当前时间
            Date date = new Date();
            //转换为字符串
            System.out.println(date.toString());
            //转换为GMT时区
            System.out.println(date.toGMTString());
            //转换为本地时区
            System.out.println(date.toLocaleString());
        }
    }
    //输出
    Sun Nov 20 10:19:25 CST 2022
    20 Nov 2022 02:19:25 GMT
    2022-11-20 10:19:25
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    3.5 日期时间格式化

    格式化日期表示将日期/时间格式转换为预先定义的日期/时间格式;
    例如将 Sun Nov 20 13:48:40 CST 2022 格式化为 2022-11-20 13:48:40

    3.5.1 DateFormat类 进行格式化

    日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间

    在这里插入图片描述
    创建 DateFormat 对象时不能使用 new 关键字,而应该使用 DateFormat 类中的静态方法 getDateInstance()

    getDateInstance()的变种有以下形式

    方法描述
    static DateFormat getDateInstance()获取具有默认格式化风格和默认语言环境的日期格式
    static DateFormat getDateInstance(int style)获取具有指定格式化风格和默认语言环境的日期格式
    static DateFormat getDateInstance(int style, Locale locale)获取具有指定格式化风格和指定语言环境的日期格式
    static DateFormat getDateTimeInstance()获取具有默认格式化风格和默认语言环境的日期/时间 格式
    static DateFormat getDateTimeInstance(int dateStyle,int timeStyle)获取具有指定日期/时间格式化风格和默认语言环境的 日期/时间格式
    static DateFormat getDateTimeInstance(int dateStyle,int timeStyle,Locale locale)获取具有指定日期/时间格式化风格和指定语言环境的 日期/时间格式
    static DateFormat getTimeInstance()获取具有默认格式化风格和默认语言环境的时间格式
    static DateFormat getTimeInstance(int style)获取具有指定格式化风格和默认语言环境的时间格式
    static DateFormat getTimeInstance(int style, Locale locale)获取具有指定格式化风格和指定语言环境的时间格式

    格式化样式主要通过 DateFormat 常量设置。将不同的常量传入getDateInstance()的方法中,以控制结果的长度。
    DateFormat 类的常量有以下几种

    • SHORT:完全为数字,如 12.5.10 或 5:30pm。
    • MEDIUM:较长,如 May 10,2016。
    • LONG:更长,如 May 12,2016 或 11:15:32am。
    • FULL:是完全指定,如 Tuesday、May 10、2012 AD 或 11:l5:42am CST
    
    import java.text.DateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    public class DateTest {
        public static void main(String[] args) {
            Date date = new Date();
            // 获取不同格式化风格和中国环境的日期
            DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT, Locale.CHINA);
            DateFormat df2 = DateFormat.getDateInstance(DateFormat.FULL, Locale.CHINA);
            DateFormat df3 = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.CHINA);
            DateFormat df4 = DateFormat.getDateInstance(DateFormat.LONG, Locale.CHINA);
           // 获取不同格式化风格和中国环境的时间
            DateFormat df5 = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.ENGLISH);
            DateFormat df6 = DateFormat.getTimeInstance(DateFormat.FULL, Locale.CHINA);
            DateFormat df7 = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.CHINA);
            DateFormat df8 = DateFormat.getTimeInstance(DateFormat.LONG, Locale.CHINA);
    
            // 将不同格式化风格的日期格式化为日期字符串
            String date1 = df1.format(date);
            String date2 = df2.format(date);
            String date3 = df3.format(date);
            String date4 = df4.format(date);
           // 将不同格式化风格的时间格式化为时间字符串
            String time1 = df5.format(date);
            String time2 = df6.format(date);
            String time3 = df7.format(date);
            String time4 = df8.format(date);
            // 输出日期
            System.out.println("SHORT格式:" + date1 + " " + time1);
            System.out.println("FULL格式:" + date2 + " " + time2);
            System.out.println("MEDIUM格式:" + date3 + " " + time3);
            System.out.println("LONG格式:" + date4 + " " + time4);
        }
    }
    //输出
    SHORT格式:22-11-20 2:24 PM
    FULL格式:20221120日 星期日 下午022459秒 CST
    MEDIUM格式:2022-11-20 14:24:59
    LONG格式:20221120日 下午022459
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    3.5.2 SimpleDateFormat类进行格式化

    DateFormat 类的子类,具有更加强大的日期格式化功能;DateFormat只能单独对日期或时间格式化,而 SimpleDateFormat可以选择任何用户定义的日期/时间格式的模式
    在这里插入图片描述
    SimpleDateFormat 类主要有如下 3 种构造方法。

    • SimpleDateFormat():用默认的格式和默认的语言环境构造 SimpleDateFormat。
    • SimpleDateFormat(String pattern):用指定的格式和默认的语言环境构造 SimpleDateFormat。
    • SimpleDateFormat(String pattern,Locale locale):用指定的格式和指定的语言环境构造 SimpleDateF ormat。

    在这里插入图片描述

    字母描述示例
    G纪元标记 根据语言环境显示Locale.CHINA 语言环境下,如:公元;Locale.US语言环境下,如:AD
    y年份。yy表示2位年份,yyyy表示4位年份使用yy 表示年份,如22;使用yyyy表示年份,例如2022
    M月份 一般用 MM 表示月份,如果使用 MMM,则会根据语言环境显示不同语言的月份使用 MM 表示的月份,如 11; 使用 MMM 表示月份,在 Locale.CHINA语言环境下,如“十月”;在 Locale.US环境下 如Nov
    d月份中的天数。一般用dd表示天数使用dd表示天数 例如:20
    h一天中的小时(1~12)。 一般使用hh表示小时如 10 (注意 10 有可能是 10 点,也可能是 22 点)
    H一天中的小时 (0~23)。如:22
    m分钟数 。一般用mm表示分钟数使用mm表示分钟数,如:59
    s秒数。一般使用ss表示秒数使用ss表示秒数,如:55
    S毫秒数 。一般使用SSS 表示毫秒数使用SSS表示毫秒数,如:234
    E星期几 。 会根据语言环境的不同,显示不同语言的星期几Locale.CHINA 语言环境下,如:星期日;在 Locale.US 语言下,如:Sun
    D一年中的日子。324 一年中的第324天
    F一个月中第几周。3 表示一个月中的第三周
    w一年中第几周 。48 表示一年中的第48周
    W一个月中第几周1
    aA.M./P.M. 或上午/下午标记。根据语言环境不同,显示不同Locale.CHINA 语言环境下,如:下午 Locale.US语言环境下,如:PM
    k一天中的小时(1~24)15 一天中的第15小时
    K一天中的小时(1~12)3 下午3小时
    z时区中国的东八区 如:+0800
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    
    public class DateTest {
        public static void main(String[] args)  {
            SimpleDateFormat sdf1 = new SimpleDateFormat("今天是:"+"yyyy年MM月dd日 HH点mm分ss秒 SSS 毫秒 E ", Locale.CHINA);
            System.out.println(sdf1.format(new Date()));
    
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss", Locale.CHINA);
            System.out.println(sdf2.format(new Date()));
        }
    }
    //输出
    今天是:20221120152737091 毫秒 星期日 
    2022-27-20 03:27:37
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    3.6 日期字符串互转
    3.6.1 DateFormat 类实现
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //将日期转为字符串
            Date date1 = new Date();
            DateFormat df1 = DateFormat.getDateInstance(DateFormat.MEDIUM);
            String strdate = df1.format(date1);
            System.out.println(strdate);
    
            //将字符串转日期
            DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM);
            Date date2 = df2.parse("1998-19-13");
            System.out.println(date2);
    
        }
    }
    //输出
    2022-11-20
    Tue Jul 13 00:00:00 CST 1999
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    3.6.2 SimpleDateFormat类实现
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            //日期转字符串
            Date date1 = new Date();
            String strdate1 = sdf.format(date1);
            System.out.println(strdate1);
    
            //字符串转日期
            Date date2 = sdf.parse("1992-09-13 08:34:45");
            System.out.println(date2.toString());
    
        }
    }
    //输出
    2022-11-20 03:32:21
    Sun Sep 13 08:34:45 CST 1992
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    3.7 日期时间比较

    boolean before(Date when)boolean after(Date when)boolean equals(Object obj)int compareTo(Date anotherDate)

    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Date date1 = sdf.parse("1992-10-08 11:23:59");
            Date date2 = sdf.parse("1992-09-13 08:34:45");
            Date date3 = sdf.parse("1992-09-13 08:34:45");
    
            System.out.println("date1:" + sdf.format(date1));
            System.out.println("date2:" + sdf.format(date2));
            System.out.println("date3:" + sdf.format(date3));
            System.out.println("********************************************************************");
            //compareTo方法比较
            System.out.println("compareTo方法比较结果1:"+date1.compareTo(date2));
            System.out.println("compareTo方法比较结果2:"+date2.compareTo(date3));
            System.out.println("compareTo方法比较结果2:"+date2.compareTo(date1));
            System.out.println("-------------------------------------------------------------------");
            //equals方法比较
            System.out.println("equals方法比较结果1:"+date1.equals(date2));
            System.out.println("equals方法比较结果2:"+date2.equals(date3));
            System.out.println("equals方法比较结果2:"+date2.equals(date1));
            System.out.println("-------------------------------------------------------------------");
            //before方法比较
            System.out.println("before方法比较结果1:"+date1.before(date2));
            System.out.println("before方法比较结果2:"+date2.before(date3));
            System.out.println("before方法比较结果2:"+date2.before(date1));
            System.out.println("-------------------------------------------------------------------");
            //after方法比较
            System.out.println("after方法比较结果1:"+date1.after(date2));
            System.out.println("after方法比较结果2:"+date2.after(date3));
            System.out.println("after方法比较结果2:"+date2.after(date1));
        }
    }
    //输出
    date1:1992-10-08 11:23:59
    date2:1992-09-13 08:34:45
    date3:1992-09-13 08:34:45
    ********************************************************************
    compareTo方法比较结果1:1
    compareTo方法比较结果2:0
    compareTo方法比较结果2:-1
    -------------------------------------------------------------------
    equals方法比较结果1:false
    equals方法比较结果2:true
    equals方法比较结果2:false
    -------------------------------------------------------------------
    before方法比较结果1:false
    before方法比较结果2:false
    before方法比较结果2:true
    -------------------------------------------------------------------
    after方法比较结果1:true
    after方法比较结果2:false
    after方法比较结果2:false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    四、 第二代日期时间类

    由于第一代日期时间类Date 存在几个严重问题:

    • 不能转换时区。除了toGMTString()可以按GMT+0:00输出外,
    • Date总是以当前计算机系统的默认时区为基础进行输出。
    • 我们也很难对日期和时间进行加减,计算两个日期相差多少天,计算某个月第一个星期一的日期等。

    由于以上诸多问题,第二代日期时间类Calendar 便来了。上一小节中我们发现Date 类下的很多方法都废弃了,当然了在Calendar 中有新的方法可以取代

    4.1 继承关系

    在这里插入图片描述
    在这里插入图片描述

    4.2 获取实例对象

    因为 Calendar 类是一个抽象类,创建 Calendar 对象不能使用 new 关键字,但是它提供了一个 getInstance() 方法来获得 Calendar类的对象

    //默认是当前日期
    Calendar c = Calendar.getInstance();  
    
    • 1
    • 2
    4.3 TimeZone 时区

    CalendarDate相比,提供了时区类TimeZone

    import java.text.ParseException;
    import java.util.TimeZone;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            // 当前时区
            TimeZone tzDefault = TimeZone.getDefault();
            System.out.println("当前时区:" + tzDefault.getID());
    
            //获取纽约时区
            TimeZone tzNY = TimeZone.getTimeZone("America/New_York");
            System.out.println("纽约时区:" + tzNY.getID());
        }
    }
    //输出
    当前时区:Asia/Shanghai
    纽约时区:America/New_York
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.TimeZone;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            // 当前时间:
            Calendar c = Calendar.getInstance();
            // 设置为纽约时区:
            c.setTimeZone(TimeZone.getTimeZone("America/New_York"));
            // 格式化显示时间:
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            sdf1.setTimeZone(TimeZone.getTimeZone("America/New_York"));
            System.out.println("纽约时间:"+sdf1.format(c.getTime()));
            
            // 设置为北京时区:
            c.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            // 格式化显示时间:
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            sdf2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            System.out.println("北京时间:"+sdf2.format(c.getTime()));
        }
    }
    //输出
    纽约时间:2022-11-22 18:49:08
    北京时间:2022-11-23 07:49:08
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    4.4 常用时间点的获取

    注:

    • 与中国人习惯不同,一年中1月的值为0。
    • 与中国人的习惯不同, 一周中的第一天为 周日. 一周的顺序依次为: 周日(1), 周一(2), 周二(3), 周三(4), 周四(5), 周五(6), 周六(7)

    Calendar类中各个常量含义

    常量含义
    Calendar.YEAR年份
    Calendar.MONTH月份
    Calendar.DAY_OF_MONTH日期
    Calendar.DATE日期,和上面的字段意义完全相同
    Calendar.HOUR12小时制的小时
    Calendar.HOUR_OF_DAY24小时制的小时
    Calendar.MINUTE分钟
    Calendar.SECOND
    Calendar.MILLISECOND毫秒
    Calendar.DAY_OF_WEEK星期几 周日(1), 周一(2), 周二(3), 周三(4), 周四(5), 周五(6), 周六(7)
    Calendar.WEEK_OF_YEAR一年中第几周
    Calendar.WEEK_OF_MONTH一月中第几周
    //获取时间点
    import java.text.ParseException;
    import java.util.Calendar;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //获取当前时间
            Calendar c = Calendar.getInstance();
            //获取年份
            System.out.println("获取年份:"+c.get(Calendar.YEAR));
            //获取月份
            System.out.println("获取月份:"+(c.get(Calendar.MONTH) + 1));
            //获取一月中的天
            System.out.println("获取一月中的天:"+c.get(Calendar.DAY_OF_MONTH));
            System.out.println("获取一月中的天:"+c.get(Calendar.DATE));
            //获取一天中的小时 24小时制
            System.out.println("获取一天中的小时(24小时制):"+c.get(Calendar.HOUR_OF_DAY));
            //获取一天中的小时 12小时制
            System.out.println("获取一天中的小时(12小时制):"+c.get(Calendar.HOUR));
            //获取分钟
            System.out.println("获取分钟:"+c.get(Calendar.MINUTE));
            //获取秒
            System.out.println("获取秒:" + c.get(Calendar.SECOND));
            //获取毫秒
            System.out.println("获取毫秒:" + c.get(Calendar.MILLISECOND));
            //获取一周中星期几
            System.out.println("获取一周中星期几:"+ c.get(Calendar.DAY_OF_WEEK));
            //获取一年中星期几
            System.out.println("获取一年中第几周:"+c.get(Calendar.WEEK_OF_YEAR));
            //获取一月中第几周
            System.out.println("获取一月中第几周:"+c.get(Calendar.WEEK_OF_MONTH));
    
            System.out.println("当前时间:"+(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DAY_OF_MONTH) +
                    " "+ c.get(Calendar.HOUR_OF_DAY) + ':' + c.get(Calendar.MINUTE) + ':' + c.get(Calendar.SECOND) +
                    ':' + c.get(Calendar.MILLISECOND) ));
        }
    }
    //输出
    获取年份:2022
    获取月份:11
    获取一月中的天:20
    获取一月中的天:20
    获取一天中的小时(24小时制):16
    获取一天中的小时(12小时制):4
    获取分钟:39
    获取秒:37
    获取毫秒:238
    获取一周中星期几:1
    获取一年中第几周:48
    获取一月中第几周:4
    当前时间:2022-11-20 16:39:37:238
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    4.5 常用时间点设置

    注:在使用set方法之前,必须先clear一下,否则很多信息会继承自系统当前时间

    4.5.1 分别对年、月、日、时、分、秒每个值进行设置
    //设置时间点 
    import java.text.ParseException;
    import java.util.Calendar;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //初始化Calendar类
            Calendar c = Calendar.getInstance();
            //将时间设置成1992-09-13 23:35:59:123
            c.clear();  //先clear一下,否则很多信息会继承自系统当前时间
            c.set(Calendar.YEAR,1992);
            c.set(Calendar.MONTH,9);
            c.set(Calendar.DAY_OF_MONTH,13);
            c.set(Calendar.HOUR_OF_DAY,23);
            c.set(Calendar.MINUTE,35);
            c.set(Calendar.SECOND,59);
            c.set(Calendar.MILLISECOND,123);
    
            System.out.println("设置好的时间为:"+(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DAY_OF_MONTH) +
                    " "+ c.get(Calendar.HOUR_OF_DAY) + ':' + c.get(Calendar.MINUTE) + ':' + c.get(Calendar.SECOND) +
                    ':' + c.get(Calendar.MILLISECOND) ));
    
        }
    }
    //输出
    设置好的时间为:1992-10-13 23:35:59:123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    4.5.2 一起设置年月日、年月日时分、年月日时分秒

    set(int year ,int month,int date)
    set(int year ,int month,int date,int hour,int minute)
    set(int year ,int month,int date,int hour,int minute,int second)

    import java.text.ParseException;
    import java.util.Calendar;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //初始化Calendar类
            Calendar c = Calendar.getInstance();
            System.out.println("当前时间为:"+(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DAY_OF_MONTH) +
                    " "+ c.get(Calendar.HOUR_OF_DAY) + ':' + c.get(Calendar.MINUTE) + ':' + c.get(Calendar.SECOND) +
                    ':' + c.get(Calendar.MILLISECOND) ));
            //将时间设置成1992-09-13 23:35:59
            c.clear();
            c.set(1992,9,13,23,35,59);
    
            System.out.println("设置好的时间为:"+(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DAY_OF_MONTH) +
                    " "+ c.get(Calendar.HOUR_OF_DAY) + ':' + c.get(Calendar.MINUTE) + ':' + c.get(Calendar.SECOND) +
                    ':' + c.get(Calendar.MILLISECOND) ));
        }
    }
    //输出
    当前时间为:2022-11-20 17:29:27:98
    设置好的时间为:1992-10-13 23:35:59:0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    4.6 时间计算

    Calendar.add() 对时间进行加减运算

    import java.text.ParseException;
    import java.util.Calendar;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //初始化Calendar类
            Calendar c = Calendar.getInstance();
            System.out.println("当前时间是:"+(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DAY_OF_MONTH) +
                    " "+ c.get(Calendar.HOUR_OF_DAY) + ':' + c.get(Calendar.MINUTE) + ':' + c.get(Calendar.SECOND) +
                    ':' + c.get(Calendar.MILLISECOND) ));
            c.add(Calendar.DATE,5);
            System.out.println("当前日期+5天后:"+(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DAY_OF_MONTH) +
                    " "+ c.get(Calendar.HOUR_OF_DAY) + ':' + c.get(Calendar.MINUTE) + ':' + c.get(Calendar.SECOND) +
                    ':' + c.get(Calendar.MILLISECOND) ));
    
            c.add(Calendar.DATE,-15);
            System.out.println("当前日期-15天后:"+(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DAY_OF_MONTH) +
                    " "+ c.get(Calendar.HOUR_OF_DAY) + ':' + c.get(Calendar.MINUTE) + ':' + c.get(Calendar.SECOND) +
                    ':' + c.get(Calendar.MILLISECOND) ));
    
        }
    }
    //输出
    当前时间是:2022-11-20 17:23:57:406
    当前日期+5天后:2022-11-25 17:23:57:406
    当前日期-15天后:2022-11-10 17:23:57:406
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    4.7 获取时间戳( 获取当前毫秒数)
    import java.text.ParseException;
    import java.util.Calendar;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //初始化Calendar类
            Calendar c = Calendar.getInstance();
            //获取毫秒数
            System.out.println(c.getTimeInMillis());
        }
    }
    //输出
    1668936885795
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    4.8 时间日期比较

    Calender.before()Calender.after()Calender.compareTo()Calender.equals()

    import java.text.ParseException;
    import java.util.Calendar;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //初始化Calendar类
            Calendar c1 = Calendar.getInstance();
            Calendar c2 = Calendar.getInstance();
            Calendar c3 = Calendar.getInstance();
    
            c1.clear();
            c2.clear();
            c3.clear();
    
            //c1设置为1992-09-13 23:35:59
            c1.set(1992,8,13 ,23,35,59);
            //c2设置为1992-10-08 21:21:55
            c2.set(1992,9,8 ,21,21,55);
            //c3设置为1992-10-08 21:21:55
            c3.set(1992,9,8 ,21,21,55);
    
            System.out.println("c1日期值:"+(c1.get(Calendar.YEAR) + "-" + (c1.get(Calendar.MONTH) + 1) + "-"+ c1.get(Calendar.DAY_OF_MONTH) +
                    " "+ c1.get(Calendar.HOUR_OF_DAY) + ':' + c1.get(Calendar.MINUTE) + ':' + c1.get(Calendar.SECOND) +
                    ':' + c1.get(Calendar.MILLISECOND) ));
            System.out.println("c2日期值:"+(c2.get(Calendar.YEAR) + "-" + (c2.get(Calendar.MONTH) + 1) + "-"+ c2.get(Calendar.DAY_OF_MONTH) +
                    " "+ c2.get(Calendar.HOUR_OF_DAY) + ':' + c2.get(Calendar.MINUTE) + ':' + c2.get(Calendar.SECOND) +
                    ':' + c2.get(Calendar.MILLISECOND) ));
    
            System.out.println("c3日期值:"+(c3.get(Calendar.YEAR) + "-" + (c3.get(Calendar.MONTH) + 1) + "-"+ c3.get(Calendar.DAY_OF_MONTH) +
                    " "+ c3.get(Calendar.HOUR_OF_DAY) + ':' + c3.get(Calendar.MINUTE) + ':' + c3.get(Calendar.SECOND) +
                    ':' + c3.get(Calendar.MILLISECOND) ));
    
            System.out.println("******************************************************************");
    
            //Calender.compareTo() 方法比较
            System.out.println("compareTo方法比较结果1:"+c1.compareTo(c2));
            System.out.println("compareTo方法比较结果2:"+c2.compareTo(c3));
            System.out.println("compareTo方法比较结果3:"+c2.compareTo(c1));
    
            System.out.println("------------------------------------------------------------------");
            //Calender.equals() 方法比较
            System.out.println("equals方法比较结果1:"+c1.equals(c2));
            System.out.println("equals方法比较结果2:"+c2.equals(c3));
            System.out.println("equals方法比较结果3:"+c2.equals(c1));
    
            System.out.println("------------------------------------------------------------------");
            //Calender.before() 方法比较
            System.out.println("before方法比较结果1:"+c1.before(c2));
            System.out.println("before方法比较结果2:"+c2.before(c3));
            System.out.println("before方法比较结果3:"+c2.before(c1));
    
            System.out.println("------------------------------------------------------------------");
            //Calender.after() 方法比较
            System.out.println("after方法比较结果1:"+c1.after(c2));
            System.out.println("after方法比较结果2:"+c2.after(c3));
            System.out.println("after方法比较结果3:"+c2.after(c1));
    
        }
    }
    //输出
    c1日期值:1992-9-13 23:35:59:0
    c2日期值:1992-10-8 21:21:55:0
    c3日期值:1992-10-8 21:21:55:0
    ******************************************************************
    compareTo方法比较结果1-1
    compareTo方法比较结果20
    compareTo方法比较结果31
    ------------------------------------------------------------------
    equals方法比较结果1false
    equals方法比较结果2true
    equals方法比较结果3false
    ------------------------------------------------------------------
    before方法比较结果1true
    before方法比较结果2false
    before方法比较结果3false
    ------------------------------------------------------------------
    after方法比较结果1false
    after方法比较结果2false
    after方法比较结果3true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    五、 第三代日期时间

    由于第二代日期类也存在着以下问题

    • 可变性:像日期这样的类应该时不可变的
    • 偏移性:年份是从1900开始的,而月份从0开始
    • 格式化:格式化只对Date类有用,Calendar则不行,要格式化只能将Calendar 转换为Date
    • 线程安全性:都不是线程安全的
    • 时区问题:时区处理麻烦
    • 闰秒问题:不能处理闰秒(每隔2天,多出1s)
      所以在JDK8中出现了第三代日期时间类,第三代日期时间API具有以下特点
    • 线程安全性: 是线程安全的。不仅没有 setter 方法,而且任何对实例的变更都会返回一个新的实例,保证原来的实例不变
    • 方便性: − 提供了大量的方法,简化了日期时间的处理
    • 时区问题:引入了 域 ( domain ) 这个概念对时区进行处理
    5.1 继承关系
    • java.time.LocalDate 用于表示 “本地日期”,无 “时间”。LocalDate 不承载时区信息。

    • java.time.LocalTime 用于表示 “本地时间”,无 “日期”。LocalTime 不承载时区信息。

    • java.time.LocalDateTime 用于表示 “本地日期与时间”。LocalDateTime 不承载时区信息。

    • java.time.ZonedDateTime 用于表示承载时区信息的时间

    • java.time.ZoneId 是引入的新的时区类

    • LocalDate 实例与 LocalTime 实例能够共同构建 LocalDateTime 实例;

    • LocalDateTime 实例能够获取 LocalDate 实例与 LocalTime 实例。

    • 可以简单地把ZonedDateTime理解成LocalDateTimeZoneId
      LocalDateTime
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    5.2 获取实例对象
    • 通过静态方法now()(获取的时间是系统当前的时间
    • 通过静态方法of()(方法参数可以指定时间
    import java.text.ParseException;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //获取当前日期时间
            LocalDateTime now = LocalDateTime.now();
            System.out.println("当前日期时间:"+now);
    
            //获取当前日期
            LocalDate nowdate = LocalDate.now();
            System.out.println("当前日期:" + nowdate);
    
            //获取当前时间
            LocalTime time = LocalTime.now();
            System.out.println("当前时间:" + time);
    
            System.out.println("********************************************");
    
            //设置日期时间
            LocalDateTime localdatetime = LocalDateTime.of(1992, 9, 13, 23, 56, 59, 333);
            System.out.println("日期时间设置为:" + localdatetime);
    
            //设置日期
            LocalDate localdate = LocalDate.of(1992, 9, 13);
            System.out.println("日期设置为:" + localdate);
    
            //设置时间
            LocalTime localtime = LocalTime.of(23, 56, 59, 333);
            System.out.println("时间设置为:" + localtime);
    
        }
    }
    //输出
    当前日期时间:2022-11-22T06:34:13.280
    当前日期:2022-11-22
    当前时间:06:34:13.280
    ********************************************
    日期时间设置为:1992-09-13T23:56:59.000000333
    日期设置为:1992-09-13
    时间设置为:23:56:59.000000333
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    5.3 获取年月日时分秒
    • getYear():获取年
    • getMonth():获得月份(返回一个 Month 枚举值)
    • getMonthValue():获得月份(1-12)
    • getDayOfMonth():获得月份天数(1-31)
    • getDayOfYear():获得年份天数(1-366)
    • getHour():获取小时
    • getMinute():获取分钟
    • getSecond():获取秒值
    • now.getNano():获取纳秒
    • getDayOfWeek():获得星期几(返回一个 DayOfWeek枚举值)
    import java.text.ParseException;
    import java.time.*;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //获取当前日期时间
            LocalDateTime now = LocalDateTime.now();
            System.out.println("当前日期时间:"+now);
    
            //获取年份
            int year = now.getYear();
            System.out.println("当前年份:" + year);
    
            //获取月份
            Month month = now.getMonth();
            int monthValue = now.getMonthValue();
            System.out.println("当前月份枚举值获取:" + month);
            System.out.println("当前月份值:" + monthValue);
    
            //获取日
            int dayOfMonth = now.getDayOfMonth();
            int dayOfYear = now.getDayOfYear();
            DayOfWeek dayOfWeek = now.getDayOfWeek();
            System.out.println("一个月中的天:" + dayOfMonth);
            System.out.println("一年中的天:" + dayOfYear);
            System.out.println("一周中的天:" + dayOfWeek);
    
            //获取小时
            int hour = now.getHour();
            System.out.println("小时:" + hour);
    
            //获取分钟
            int minute = now.getMinute();
            System.out.println("分钟:" + minute);
    
            //获取秒
            int second = now.getSecond();
            System.out.println("秒:" + second);
    
            //获取纳秒
            int nano = now.getNano();
            System.out.println("纳秒:" + nano);
            
        }
    }
    //输出
    当前日期时间:2022-11-22T06:53:29.172
    当前年份:2022
    当前月份枚举值获取:NOVEMBER
    当前月份值:11
    一个月中的天:22
    一年中的天:326
    一周中的天:TUESDAY
    小时:6
    分钟:53
    秒:29
    纳秒:172000000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    5.4 日期时间比较
    • isAfter():判断一个日期是否在指定日期之后
    • isBefore():判断一个日期是否在指定日期之前
    • isEqual():判断两个日期是否相同
    • isLeapYear():判断是否是闰年(注意是LocalDate类 和 LocalDateTime类特有的方法)
    • compareTo(): 两个日期比较返回0,1,-1
    import java.text.ParseException;
    import java.time.*;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //dateTime1时间初始化为1992-09-13 23:35:59
            LocalDateTime dateTime1 = LocalDateTime.of(1992, 9, 13, 23, 35, 59);
            //dateTime2时间初始化为1992-10-08 23:35:50
            LocalDateTime dateTime2 = LocalDateTime.of(1992, 10, 8, 23, 35, 50);
            //dateTime3时间初始化为1992-10-08 23:35:50
            LocalDateTime dateTime3 = LocalDateTime.of(1992, 10, 8, 23, 35, 50);
    
            System.out.println("******************输出三个时间*****************************");
            System.out.println("dateTime1时间1:"+dateTime1);
            System.out.println("dateTime2时间2:"+dateTime2);
            System.out.println("dateTime3时间3:"+dateTime3);
    
    
            //isAfter()方法比较
            System.out.println("------------isAfter()方法比较-------------------");
            System.out.println("dateTime1在dateTime2之后?"+dateTime1.isAfter(dateTime2));
            System.out.println("dateTime2在dateTime3之后?"+dateTime2.isAfter(dateTime3));
            System.out.println("dateTime2在dateTime1之后?"+dateTime2.isAfter(dateTime1));
    
    
            //isBefore()方法比较
            System.out.println("------------isBefore()方法比较-------------------");
            System.out.println("dateTime1在dateTime2之前?"+dateTime1.isBefore(dateTime2));
            System.out.println("dateTime2在dateTime3之前?"+dateTime2.isBefore(dateTime3));
            System.out.println("dateTime2在dateTime1之前?"+dateTime2.isBefore(dateTime1));
    
    
            //isEqual()方法比较
            System.out.println("------------isEqual()方法比较-------------------");
            System.out.println("dateTime1与dateTime2相等?"+dateTime1.isEqual(dateTime2));
            System.out.println("dateTime2与dateTime3相等?"+dateTime2.isEqual(dateTime3));
            System.out.println("dateTime2与dateTime1相等?"+dateTime2.isEqual(dateTime1));
    
            //compareTo()方法比较
            System.out.println("------------compareTo()方法比较-------------------");
            System.out.println("dateTime1与dateTime2比较?"+dateTime1.compareTo(dateTime2));
            System.out.println("dateTime2与dateTime3比较?"+dateTime2.compareTo(dateTime3));
            System.out.println("dateTime2与dateTime1比较?"+dateTime2.compareTo(dateTime1));
        }
    }
    //输出
    ******************输出三个时间*****************************
    dateTime1时间11992-09-13T23:35:59
    dateTime2时间21992-10-08T23:35:50
    dateTime3时间31992-10-08T23:35:50
    ------------isAfter()方法比较-------------------
    dateTime1在dateTime2之后?false
    dateTime2在dateTime3之后?false
    dateTime2在dateTime1之后?true
    ------------isBefore()方法比较-------------------
    dateTime1在dateTime2之前?true
    dateTime2在dateTime3之前?false
    dateTime2在dateTime1之前?false
    ------------isEqual()方法比较-------------------
    dateTime1与dateTime2相等?false
    dateTime2与dateTime3相等?true
    dateTime2与dateTime1相等?false
    ------------compareTo()方法比较-------------------
    dateTime1与dateTime2比较?-1
    dateTime2与dateTime3比较?0
    dateTime2与dateTime1比较?1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    5.5 日期时间计算
    5.5.1 增加年月日时分秒
    • plusYears(int offset):增加指定年份
    • plusMonths(int offset):增加指定月份
    • plusDates(int offset):增加指定日
    • plusHours(int offset):增加指定时
    • plusMinuets(int offset):增加指定分
    • plusSeconds(int offset):增加指定秒
    • plusNanos(int offset):增加指定纳秒
    • plusWeeks(int offset):增加指定周
    import java.text.ParseException;
    import java.time.*;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
           //获取当前时间
            LocalDateTime now = LocalDateTime.now();
    
            System.out.println("当前时间:" + now);
    
            //两年后
            LocalDateTime localDateTime1 = now.plusYears(2);
            System.out.println("两年以后:" + localDateTime1);
    
            //三个月后
            LocalDateTime localDateTime2 = now.plusMonths(3);
            System.out.println("三个月后:" + localDateTime2);
    
            //五天后
            LocalDateTime localDateTime3 = now.plusDays(5);
            System.out.println("五天后:" + localDateTime3);
    
            //4小时后
            LocalDateTime localDateTime4 = now.plusHours(4);
            System.out.println("4小时后:"+localDateTime4);
    
            //30分钟后
            LocalDateTime localDateTime5 = now.plusMinutes(30);
            System.out.println("30分钟后:" + localDateTime5);
    
            //80秒后
            LocalDateTime localDateTime6 = now.plusSeconds(80);
            System.out.println("80秒后:" + localDateTime6);
    
            //3周后
            LocalDateTime localDateTime7 = now.plusWeeks(3);
            System.out.println("3周后:"+localDateTime7);
    
    
        }
    }
    //输出
    当前时间:2022-11-22T07:28:55.129
    两年以后:2024-11-22T07:28:55.129
    三个月后:2023-02-22T07:28:55.129
    五天后:2022-11-27T07:28:55.129
    4小时后:2022-11-22T11:28:55.129
    30分钟后:2022-11-22T07:58:55.129
    80秒后:2022-11-22T07:30:15.129
    3周后:2022-12-13T07:28:55.129
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    5.5.1 减少年月日时分秒
    • minusYears(int offset):减少指定年
    • minusMonths(int offset):减少指定月
    • minusDates(int offset):减少指定日
    • minusHours(int offset):减少指定时
    • minusMinuets(int offset):减少指定分
    • minusSeconds(int offset):减少指定秒
    • minusNanos(int offset):减少指定纳秒
    • minusWeeks(int offset):减少指定周
    import java.text.ParseException;
    import java.time.*;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
           //获取当前时间
            LocalDateTime now = LocalDateTime.now();
    
            System.out.println("当前时间:" + now);
    
            //10年以前
            LocalDateTime localDateTime1 = now.minusYears(10);
            System.out.println("10年以前:" + localDateTime1);
    
            //三个月以前
            LocalDateTime localDateTime2 = now.minusMonths(3);
            System.out.println("三个月以前:" + localDateTime2);
    
            //五天前
            LocalDateTime localDateTime3 = now.minusDays(5);
            System.out.println("五天前:" + localDateTime3);
    
            //4小时前
            LocalDateTime localDateTime4 = now.minusHours(4);
            System.out.println("4小时前:"+localDateTime4);
    
            //30分钟前
            LocalDateTime localDateTime5 = now.minusMinutes(30);
            System.out.println("30分钟前:" + localDateTime5);
    
            //80秒前
            LocalDateTime localDateTime6 = now.plusSeconds(80);
            System.out.println("80秒前:" + localDateTime6);
    
            //3周后
            LocalDateTime localDateTime7 = now.minusWeeks(3);
            System.out.println("3周前:"+localDateTime7);
    
        }
    }
    //输出
    当前时间:2022-11-22T07:33:14.203
    10年以前:2012-11-22T07:33:14.203
    三个月以前:2022-08-22T07:33:14.203
    五天前:2022-11-17T07:33:14.203
    4小时前:2022-11-22T03:33:14.203
    30分钟前:2022-11-22T07:03:14.203
    80秒前:2022-11-22T07:34:34.203
    3周前:2022-11-01T07:33:14.203
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    5.5.3 时间调节器

    可以更加灵活地处理一些复杂的日期,例如:实现日期调整到下个周日、下个工作日,或者是下个月的第一天等等,也可以增加自己定制功能

    import java.text.ParseException;
    import java.time.*;
    import java.time.temporal.TemporalAdjuster;
    import java.time.temporal.TemporalAdjusters;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
           //获取当前时间
            LocalDateTime now = LocalDateTime.now();
    
            System.out.println("当前时间:" + now);
    
            System.out.println("------------------下个月第一天--------------------------");
    
            //下个月第一天
            TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstDayOfNextMonth();
            LocalDateTime localDateTime1 = now.with(temporalAdjuster);
            System.out.println(localDateTime1);
    
            System.out.println("------------------下周周五--------------------------");
            //下周周五
            TemporalAdjuster next = TemporalAdjusters.next(DayOfWeek.FRIDAY);
            LocalDateTime localDateTime12 = now.with(next);
            System.out.println(localDateTime12);
            
        }
    }
    //输出
    当前时间:2022-11-22T07:56:56.906
    ------------------下个月第一天--------------------------
    2022-12-01T07:56:56.906
    ------------------下周周五--------------------------
    2022-11-25T07:56:56.906
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    5.5.4 with方法使用
    • withYear(int year):指定年
    • withMonth(int month):指定月
    • withDayOfMonth(int dayOfMonth):指定日
    • withDayOfYear(int dayOfYear):指定日
    • with(TemporalAdjuster adjuster):指定特殊时间
    import java.text.ParseException;
    import java.time.*;
    import java.time.temporal.TemporalAdjusters;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
           //获取当前时间
            LocalDateTime now = LocalDateTime.now();
    
            System.out.println("当前时间:" + now);
            //指定1992年
            LocalDateTime localDateTime1 = now.withYear(1992);
            System.out.println("指定1992年:" + localDateTime1);
    
            //指定11月
            LocalDateTime localDateTime2 = now.withMonth(11);
            System.out.println("指定11月份:" + localDateTime2);
    
            //指定11日
            LocalDateTime localDateTime3 = now.withDayOfMonth(11);
            System.out.println("指定11日:" + localDateTime3);
    
            //指定特殊日期
            LocalDateTime localDateTime4 = now.with(TemporalAdjusters.firstDayOfMonth());
            System.out.println("指定当月第一天:"+localDateTime4);
        }
    }
    //输出
    当前时间:2022-11-22T07:50:02.386
    指定1992年:1992-11-22T07:50:02.386
    指定11月份:2022-11-22T07:50:02.386
    指定11日:2022-11-11T07:50:02.386
    指定当月第一天:2022-11-01T07:50:02.386
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    5.5.5 计算两个“日期”间隔

    Period 用于计算两个日期间隔, between() 方法只能接收 LocalDate 类型的参数

    • 静态方法 between():计算两个日期之间的间隔
    • getYears():获取年份
    • getMonths():获取月份
    • getDays():获取天数
    import java.text.ParseException;
    import java.time.*;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //设置生日
            LocalDate birth = LocalDate.of(2004, 10, 8);
            //获取当前时间
            LocalDate now = LocalDate.now();
    
            //计算两个时间间隔
            Period between = Period.between(birth, now);
            int years = between.getYears();
            int months = between.getMonths();
            int days = between.getDays();
    
            System.out.println("从出生到现在" + years + "年" + months + "月" + days + "天了");
    
    
        }
    }
    //输出
    从出生到现在18115天了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    5.5.6 计算两个“时间”间隔

    Duration 表示一个时间段,Duration 包含两部分:seconds 表示秒,nanos 表示纳秒,它们的组合表达了时间长度。
    因为 Duration 表示时间段,所以 Duration 类中不包含 now() 静态方法。注意,Duration 不包含毫秒这个属性。
    Duration只能处理两个LocalTime, LocalDateTime, ZonedDateTime; 如果传入的是LocalDate,将会抛出异常

    • 静态方法 between():计算两个时间的间隔,默认是秒
    • toDays():将时间转换为以天为单位的
    • toHours():将时间转换为以时为单位的
    • toMinutes():将时间转换为以分钟为单位的
    • toMillis():将时间转换为以毫秒为单位的
    • toNanos():将时间转换为以纳秒为单位的
    import java.text.ParseException;
    import java.time.*;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            LocalTime beginTime = LocalTime.of(0, 1, 2);
            LocalTime now = LocalTime.now();
    
            Duration between = Duration.between(beginTime, now);
    
            long days = between.toDays();
            long hours = between.toHours();
            long minutes = between.toMinutes();
            long millis = between.toMillis();
            long nanos = between.toNanos();
    
            System.out.println("从0点1分1秒到现在一共" + days + "天" );
            System.out.println("从0点1分1秒到现在一共" + hours + "小时" );
            System.out.println("从0点1分1秒到现在一共" + minutes + "分" );
            System.out.println("从0点1分1秒到现在一共" + millis/1000 + "秒" );
            System.out.println("从0点1分1秒到现在一共" + nanos + "纳秒" );
    
        }
    }
    //输出011秒到现在一共0天
    从011秒到现在一共6小时
    从011秒到现在一共381分
    从011秒到现在一共22888秒
    从011秒到现在一共22888801000000纳秒
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    5.6 获取时间戳

    java.time.Instant 可以获取时间线上的一个瞬时点,精确到纳秒级

    • now(): 获取实例化对象。默认获取出来的是默认时区,和我们(东八区)相差8小时
    • atOffset():设置偏移量
    • atZone():获取系统默认时区时间,参数是一个时区的编号(可以通过时区编号类获取ZonedDateTime类的对象)
    • getEpochSecond():获取从1970-01-01 00:00:00到当前时间的秒数
    • toEpochMilli():获取从1970-01-01 00:00:00到当前时间的毫秒数
    • getNano():获取从1970-01-01 00:00:00到当前时间的纳秒数
    • ofEpochSecond():给计算机元年增加秒数
    • ofEpochMilli():给计算机元年增加毫秒数
    import java.text.ParseException;
    import java.time.*;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //从1970-01-01 00:00:00 截止到当前时间的毫秒值(时区不是中国的)
            Instant now = Instant.now();
            System.out.println("1970-01-01 00:00:00到默认时区当前日期:" + now);
    
            //获取当前时区的,我们可以添加偏移量,返回偏移过后的日期
            OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
            System.out.println("1970-01-01 00:00:00到当前时区日期:"+offsetDateTime);
    
    
            //1970-01-01 00:00:00 截止到当前时间间隔的毫秒值
            long ll = now.toEpochMilli();
            System.out.println("1970-01-01 00:00:00到当前时间间隔的毫秒值:" + ll);
    
            //1970-01-01 00:00:00 截止到当前时间间隔的秒数
            long epochSecond = now.getEpochSecond();
            System.out.println("1970-01-01 00:00:00 到当前时间间隔的秒数:" + epochSecond);
    
    
            //ofEpochMilli() 给计算机元年增加毫秒数
            Instant instant = Instant.ofEpochMilli(1000 * 60 * 60 * 24);
            System.out.println("计算机元年增加1天(86400000毫秒):"+instant);
    
            //ofEpochSecond() 方法 给计算机元年增加秒数
            Instant instant1 = Instant.ofEpochSecond(60 * 60 * 24);
            System.out.println("计算机元年增加1天(86400秒):"+instant1);
    
        }
    }
    //输出
    1970-01-01 00:00:00到默认时区当前日期:2022-11-22T23:12:40.988Z
    1970-01-01 00:00:00到当前时区日期:2022-11-23T07:12:40.988+08:00
    1970-01-01 00:00:00到当前时间间隔的毫秒值:1669158760988
    1970-01-01 00:00:00 到当前时间间隔的秒数:1669158760
    计算机元年增加1天(86400000毫秒):1970-01-02T00:00:00Z
    计算机元年增加1天(86400秒):1970-01-02T00:00:00Z
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    5.7 带时区的日期时间

    ZonedDateTime是带有带有特定时区的日期时间类,类的方法和用法和 LocalDateTime 基本一样。
    可以简单地把ZonedDateTime理解成LocalDateTimeZoneId
    ZoneIdjava.time引入的新的时区类

    5.7.1 获取不同时区当前时间
    import java.text.ParseException;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.util.Set;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //获取世界各个地方的时区编号
            Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
            for (String availableZoneId : availableZoneIds) {
                System.out.println(availableZoneId);
            }
            System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++");
    
            //获取系统默认时区编号
            ZoneId zoneId = ZoneId.systemDefault();
            System.out.println("系统默认时区编号:" + zoneId);
            System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++");
    
            ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区
            System.out.println("获取默认时区时间:"+zbj);
    
            System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++");
            ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/New_York")); // 用指定时区获取当前时间
            System.out.println("获取指定时区时间:"+zny);
        }
    }
    **注:时区不同,但表示的时间都是同一时刻**
    
    //输出
    Asia/Aden
    America/Cuiaba
    Etc/GMT+9
    ....... 由于时区比较多,这里就不一一例举了
    Europe/Athens
    US/Pacific
    Europe/Monaco
    +++++++++++++++++++++++++++++++++++++++++++++++
    系统默认时区编号:Asia/Shanghai
    +++++++++++++++++++++++++++++++++++++++++++++++
    获取默认时区时间:2022-11-23T21:24:03.304+08:00[Asia/Shanghai]
    +++++++++++++++++++++++++++++++++++++++++++++++
    获取指定时区时间:2022-11-23T08:24:03.305-05:00[America/New_York]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    5.7.2 设置一个时区时间
    import java.text.ParseException;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            LocalDateTime localDateTime = LocalDateTime.of(1992, 9, 13, 23, 35, 59);
    
            ZonedDateTime zonedDateTime1 = localDateTime.atZone(ZoneId.systemDefault());
            ZonedDateTime zonedDateTime2 = localDateTime.atZone(ZoneId.of("America/New_York"));
    
            System.out.println("默认时区时间:"+zonedDateTime1);
            System.out.println("America/New_York时区时间:"+zonedDateTime2);
        }
    }
    //输出
    默认时区时间:1992-09-13T23:35:59+08:00[Asia/Shanghai]
    America/New_York时区时间:1992-09-13T23:35:59-04:00[America/New_York]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注:它的日期和时间与LocalDateTime相同,但附加的时区不同,因此是两个不同的时刻

    5.7.3 时区转换

    将关联时区转换到另一个时区,转换后日期和时间都会相应调整

    import java.text.ParseException;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //以中国时区获取当前时间
            ZonedDateTime now1 = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
            //将中国时间转换为美国纽约时间
            ZonedDateTime zonedDateTime = now1.withZoneSameInstant(ZoneId.of("America/New_York"));
    
            System.out.println("中国时区当前时间:" + now1);
            System.out.println("将中国时间转换为美国纽约时间:"+zonedDateTime);
    
        }
    }
    //输出
    中国时区当前时间:2022-11-23T21:43:31.065+08:00[Asia/Shanghai]
    将中国时间转换为美国纽约时间:2022-11-23T08:43:31.065-05:00[America/New_York]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    5.7.4 日期时间格式化

    第一代Date对象用SimpleDateFormat进行格式化显示,而DateTimeFormatter用于解析第三代日期字符串和格式化日期输出

    import java.text.ParseException;
    import java.time.LocalDateTime;
    
    import java.time.format.DateTimeFormatter;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //指定日期格式
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
            LocalDateTime now = LocalDateTime.now();
    
            String format = dateTimeFormatter.format(now);
            System.out.println("未格式化日期显示:" + now);
            System.out.println("当前日期格式化后:" + format);
    
        }
    }
    //输出
    未格式化日期显示:2022-11-23T21:51:00.197
    当前日期格式化后:2022-11-23 09:51:00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    5.7.5 日期字符串转日期
    import java.text.ParseException;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    
    import java.time.format.DateTimeFormatter;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //指定日期格式
            DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDate localDate = LocalDate.parse("1992-09-13", dateTimeFormatter1);
            System.out.println("字符串转LocalDate:" + localDate);
          
            LocalDateTime localDateTime = LocalDateTime.parse("1992-09-13 23:35:59", dateTimeFormatter2);
            System.out.println("字符串转LocalDateTime:" + localDateTime);
    
    
        }
    }
    //输出
    字符串转LocalDate:1992-09-13
    字符串转LocalDateTime:1992-09-13T23:35:59
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    六、三代日期之间相互转换

    由于历史遗留问题,有时候我们不得不与遗留代码打交道。这时就涉及了三代日期时间之间的相互转换

    注: 在转换中我们需要特别注意,java8之前Date是包含日期和时间的,而LocalDate只包含日期LocalTime只包含时间,所以与Date与之互转过程中,会丢失日期或者时间。最好是转换成LocalDateTime,这样就不存在日期或时间丢失问题

    6.1 Calendar 与 Date 互转
    6.1.1 Date 转换为Calendar
    import java.text.ParseException;
    import java.util.Calendar;
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //Date 转换为Calendar
            Date date = new Date();
            System.out.println("当前Date时间为:"+date);
            Calendar cal= Calendar.getInstance();
            cal.setTime(date);
            System.out.println("Date转换为Calendar后:"+(cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-"+ cal.get(Calendar.DAY_OF_MONTH) +
                    " "+ cal.get(Calendar.HOUR_OF_DAY) + ':' + cal.get(Calendar.MINUTE) + ':' + cal.get(Calendar.SECOND)));
    
        }
    }
    //输出
    当前Date时间为:Fri Nov 25 07:17:06 CST 2022
    Date转换为Calendar后:2022-11-25 7:17:6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    6.1.2 Calendar 转换为Date
    import java.text.ParseException;
    import java.util.Calendar;
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //Calendar 转换为Date
            Calendar cal=Calendar.getInstance();
            System.out.println("Calendar获取的当前时间是:"+(cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-"+ cal.get(Calendar.DAY_OF_MONTH) +
                    " "+ cal.get(Calendar.HOUR_OF_DAY) + ':' + cal.get(Calendar.MINUTE) + ':' + cal.get(Calendar.SECOND)));
    
            Date date=cal.getTime();
            System.out.println("当前Date时间为:"+date);
        }
    }
    //输出
    Calendar获取的当前时间是:2022-11-25 7:17:29
    当前Date时间为:Fri Nov 25 07:17:29 CST 2022
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    6.2 Date和Instant互换
    6.2.1 Date转为Instant
    import java.text.ParseException;
    import java.time.Instant;
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //Date转为Instant
            Date date = new Date();
            System.out.println("当前Date获取的时间是:"+date);
            Instant instant = date.toInstant();
            System.out.println("转为Instant后的时间是:"+instant);
        }
    }
    //输出
    当前Date获取的时间是:Fri Nov 25 07:27:13 CST 2022
    转为Instant后的时间是:2022-11-24T23:27:13.860Z
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    6.2.2 Instant转为Date
    import java.text.ParseException;
    import java.time.Instant;
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //Instant转为Date
            Instant instant  = Instant.now();
            System.out.println("Instant获取的时间是:"+instant);
            Date date = Date.from(instant);
            System.out.println("转换为Date后:"+date);
        }
    }
    //输出
    Instant获取的时间是:2022-11-24T23:29:18.857Z
    转换为Date后:Fri Nov 25 07:29:18 CST 2022
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    6.3 Date与LocalDateTime互转
    6.3.1 Date转LocalDateTime
    import java.text.ParseException;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //Date 转LocalDateTime
            Date date = new Date();
            System.out.println("Date获取的当前时间" + date);
    
            LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            System.out.println("第一种方式转为LocalDateTime后: " + localDateTime);
    
            LocalDateTime localDateTime1 = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
            System.out.println("第二种方式转为localDateTime2: " + localDateTime1);
    
    
        }
    }
    //输出
    Date获取的当前时间Fri Nov 25 07:35:04 CST 2022
    第一种方式转为LocalDateTime后: 2022-11-25T07:35:04.379
    第二种方式转为localDateTime2: 2022-11-25T07:35:04.379
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    6.3.2 LocalDateTime 转Date
    import java.text.ParseException;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.util.Date;
    
    public class DateTest {
        public static void main(String[] args) throws ParseException {
            //LocalDateTime 转 Date
            LocalDateTime localDateTime = LocalDateTime.now();
            System.out.println("localDateTime获取的当前时间: " + localDateTime);
    
            Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
            System.out.println("转为Date后的时间: " + date);
    
        }
    }
    //输出
    localDateTime获取的当前时间: 2022-11-25T07:36:58.216
    转为Date后的时间: Fri Nov 25 07:36:58 CST 2022
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    七、阿里巴巴关于日期时间编程规约

    阿里巴巴java开发手册,第一章1.5小结对日期时间做了相关规约。这里的规约也值得我们每个开发者遵守

    ①【强制】在日期格式化时,传入pattern中表示年份统一使用小写y

    日期格式化时,yyyy表示当天所在的年,大写的YYYY表示当天所在的周所属的年份。一周以周日开始,周六结束,只要本周跨年,返回的YYYY就是下一年。

    //正例
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    
    • 1
    • 2

    ②【强制】在日期格式中,分清楚大写的M小写的m大写的H小写的h分别代表的含义

    • 表示月份,用大写M
    • 表示分钟,用小写m
    • 表示24小时制,用大写H
    • 表示12小时制,用小写h

    ③ 【强制】获取当前毫秒数,是System.currentTimeMillis();而不是new Date().getTime()。

    说明:如果像获取更加精确的纳秒级时间值,则使用System.nanoTime() 的方法。在JDK8中,针对时间等场景,推荐使用Instant类

    ④ 【强制】不允许在程序的任何地方使用:
    1)java.sql.Date;
    2) java.sql.Time;
    3) java.sql.Timestamp;

    说明:第1个不记录时间,getHours() 抛出异常;
    第2个不记录日期,getYear() 抛出异常
    第3个在构造方法supper((time/1000)*1000)时,在Timestamp属性henanos中分别存贮秒和纳秒信息

    ⑤【强制】不要在程序中写死一年未365天,避免在闰年时出现日期转换错误或程序逻辑错误。
    //正列

    //获取几年的天数
    int days =localDate.now().lengthOfYear();
    //获取某年的天数
    Localdate.of(2022,1,2).lengthOfYear();
    
    • 1
    • 2
    • 3
    • 4

    //反列

    //第一种情况:在闰年(366天)时,出现数组越界异常
    int[] dayArray = new int[365]
    //第二种情况:一年有效期会员制,今年1月26日注册,
    //一年未365天,返回的却是1月25日
    Calendar calendar = Calendar.getInstance();
    calendar.set(2022,0,26);
    calendar.add(Calendar.DATE,365);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ⑥ 【推荐】避免出现闰年2月问题。闰年2月有29天,一年后的那一天不可能是2月29日。
    ⑦ 【推荐】使用枚举值指代月份(month)取值在0~11之间

    说明:参考JDK原生注释:Month value is 0-based.e.g.0 for January
    //正例
    用Calendar.JANUARY、Calendar.FEBRUARY、Calendar.MARCH等指代月份,进行传参或比较

    本期内容就到这了,我们下期再见(●’◡’●)

  • 相关阅读:
    太强了!有了这个 GitHub 热门工具,15 分钟内把微信小程序搬进 App!
    Flink—— Data Source 介绍
    VRTK4⭐四.和 UI 元素交互
    MySQL - 深入解析MySQL索引数据结构
    【SEC 学习】美化 Linux 终端
    如果你不只是个点工,那你应该知道 前后端分离与不分离的区别
    堆和堆排序
    Redis String类型使用方法
    银行 Zabbix 监控架构分享
    直播课堂系统12--整合Nacos和gateway
  • 原文地址:https://blog.csdn.net/rong0913/article/details/127877209