API篇(JavaSE - 日期类(Date...))(持续更新迭代)

目录

一、第一代日期类(Date,DateFormat)

1. Date

a. 简介

b. 常用API

c. 构造方法

d. 常用方法

boolean after(Dtae when)

boolean before(Dtae when)

compareTo(Date date)

equals(Object date)

getTime()

toString()

2. DateFormat & SimpleDateFormat

a. DateFormat(抽象类)

ⅰ. 实例化DateFormat

ⅱ. 日期格式

1. 美式日期格式

2. 中式日期格式

b. SimpleDateFormat类

ⅰ. 日期模板

ⅱ. 使用

ⅲ. 示例

c. DateFormat 和SimpleDateFormat 的区别

d. 演示示例

ⅰ. 使用Date类获取时间的信息

ⅱ. SimpleDateFormat简单日期格式化类的使用

ⅲ. 使用SimpleDateFormat解析字符串时间成为日期对象

ⅳ. 秒杀案例

ⅴ. String转换成Date对象

二、第二代日期类(Calendar)

1. 简介

2. 演示示例

a. 日历类 Calendar

三、第三代日期类(JDK8新特性)

1. 前面两代缺点

a. 设计很差

b. 非线程安全

c. 时区处理麻烦

2. 演示示例

3. 新增日期时间 API

4. JDK 8的日期和时间类

a. LocalDate & LocalTime & LocalDateTime

ⅰ. 日期时间修改

ⅱ. 日期时间的比较

b. DateTimeFormatter(时间格式化与解析)

c. Instant(时间戳)

d. Duration/Period(计算日期时间差类)

e. TemporalAdjuster & TemporalAdjusters(时间校正器)

f. 设置日期时间的时区

g. 总结


一、第一代日期类(Date,DateFormat)

1. Date

a. 简介

一般常用的是Java.util.Date包下的Date类,在java.sql.Date包下也有一个Date类,sql包下的Date

类主要用于和数据库打交道,其内容只包括日期,没有时间,util包下的Date类用于平常日期使

用,其内容包括日期和时间。

Date类表示系统特定的时间戳,可以精确到毫秒。

Date类中的大部分方法都过时了或者被Calendar类中的方法所取代

b. 常用API

c. 构造方法

Date类有两个构造方法,Date对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。

  • 无参构造方法Date():此种形式表示分配一个Date对象,并初始化,以便他代表他被分配的时间,精确到毫秒,使用该构造方法创建的对象可以获取本地的当前时间。

示例代码如下:

Date d1=new Date();
System.out.println(d1);//可以输出本地的当前时间
  • 带参构造方法Date(long date):此种形式表示分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数(也就是从GMT(格林尼治时间)时间1970年1月1日0时0分0秒开始经过参数date指定的毫秒数)。

示例代码如下:

long date = 24*60*60*1000;//1秒=1000毫秒,该时间为一天24小时
Date d2 = new Date(date);
System.out.println(d2);//输出从GMT基准时间过了一天后的时间
//输出:Fri Jan 02 08:00:00 CST 1970(中央标准时间)

d. 常用方法

boolean after(Dtae when)

boolean after(Dtae when)方法的Date对象是否在指定日期之后

//public Date():分配一个Date对象,并初始化,以便他代表他被分配的时间,精确到毫秒
Date d1=new Date();
System.out.println(d1);
 
//public Date(long date):分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date=24*60*60*1000;
Date d2=new Date(date);
System.out.println(d2);
System.out.println(d2.after(d1));//输出:false
boolean before(Dtae when)

判断判断调用此方法的Date对象是否在指定日期之前

//public Date():分配一个Date对象,并初始化,以便他代表他被分配的时间,精确到毫秒
Date d1=new Date();
System.out.println(d1);
 
//public Date(long date):分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date=24*60*60*1000;
Date d2=new Date(date);
System.out.println(d2);
System.out.println(d2.before(d1));//输出:true
compareTo(Date date)

比较当前调用此方法的Date对象与指定日期,两者相等时返回0,调用对象在指定日期之前则返回负数,

反之返回正数

//public Date():分配一个Date对象,并初始化,以便他代表他被分配的时间,精确到毫秒
Date d1=new Date();
System.out.println(d1);
 
//public Date(long date):分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date=24*60*60*1000;
Date d2=new Date(date);
System.out.println(d2);
System.out.println(d2.compareTo(d1));//输出:-1
equals(Object date)

当调用此方法的Date对象和指定日期相等时返回true,否则返回false

//public Date():分配一个Date对象,并初始化,以便他代表他被分配的时间,精确到毫秒
Date d1=new Date();
System.out.println(d1);
 
//public Date(long date):分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date=24*60*60*1000;
Date d2=new Date(date);
System.out.println(d2);
System.out.println(d2.equals(d1));//输出:false
getTime()

返回自1970年1月1日0时0分0秒GMT以来此Date对象表示的毫秒数

//public Date():分配一个Date对象,并初始化,以便他代表他被分配的时间,精确到毫秒
Date d1=new Date();
System.out.println(d1);
 
//public Date(long date):分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date=24*60*60*1000;
Date d2=new Date(date);
System.out.println(d2);
System.out.println(d2.getTime());//输出:86400000=24*60*60*1000
toString()

获取当前日期和时间并用以下形式的输出:dow mon dd hh:mm:ss zzz yyyy;dow是一周中的某一天

(Sun,Mon,Tue,Wed,Thu,Fri,Sat)

//public Date():分配一个Date对象,并初始化,以便他代表他被分配的时间,精确到毫秒
Date d1=new Date();
System.out.println(d1);
 
//public Date(long date):分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date=24*60*60*1000;
Date d2=new Date(date);
System.out.println(d2);
System.out.println(d2.toString());//输出:Fri Jan 02 08:00:00 CST 1970

2. DateFormat & SimpleDateFormat

a. DateFormat(抽象类)

此类是一个日期的格式化类,用来格式化日期。

具体日期可以通过java.util.Date类来获取。

DateFormat类的定义:此类是定义在java.test包中的。

public abstract class DateFormat extends Format
ⅰ. 实例化DateFormat

DateFormat是一个抽象类,按照以住的思路,直接使用其子类实例化即可。

但是DateFormat 类本身的内部提供了可以直接为其实例化的操作。

//得到日期的DateFormat对象:
public static final DateFormat getDateInstance();

//得到日期时间的DateFormat对象:
public static final DateFormat getDateTimeInstance();

//使用DateFormat类格式化Date类日期
public final String format(Date date)
ⅱ. 日期格式
1. 美式日期格式
import java.text.DateFormat ;
import java.util.Date ;
public class DateDemo03{
    public static void main(String args[]){
        DateFormat df1 = null ;     // 声明一个DateFormat
        DateFormat df2 = null ;     // 声明一个DateFormat
        df1 = DateFormat.getDateInstance() ;    // 得到日期的DateFormat对象
        df2 = DateFormat.getDateTimeInstance() ;    // 得到日期时间的DateFormat对象
        System.out.println("DATE:" + df1.format(new Date())) ; // 按照日期格式化
        System.out.println("DATETIME:" + df2.format(new Date())) ;   // 按照日期时间格式化

    }
};
2. 中式日期格式

中式日期格式(通过Locale对象指定要显示的区域,指定的区域是中国)

import java.text.DateFormat ;  
import java.util.Date ;  
import java.util.Locale ;  
public class DateDemo04{  
    public static void main(String args[]){  
        DateFormat df1 = null ;     // 声明一个DateFormat  
        DateFormat df2 = null ;     // 声明一个DateFormat  
        df1 = DateFormat.getDateInstance(DateFormat.YEAR_FIELD,new Locale("zh","CN")) ; // 得到日期的DateFormat对象  
        df2 = DateFormat.getDateTimeInstance(DateFormat.YEAR_FIELD,DateFormat.ERA_FIELD,new Locale("zh","CN")) ;    // 得到日期时间的DateFormat对象  
        System.out.println("DATE:" + df1.format(new Date())) ; // 按照日期格式化  
        System.out.println("DATETIME:" + df2.format(new Date())) ;   // 按照日期时间格式化  

    }  
};

b. SimpleDateFormat类

SimpleDateFormat函数的继承关系:

java.lang.Object
|
+—-java.text.Format
   |
   +—-java.text.DateFormat
      |
      +—-java.text.SimpleDateFormat

将一种日期格式变为另外一种日期格式

原始日期:2008-10-19   10:11:30.345

转换后日期:2008 年 10 月 19 日    10 点 11 分 30 秒 345 毫秒
ⅰ. 日期模板

首先准备好一个日期格式模板,根据模板的格式来转化日期。

ⅱ. 使用

在构造对象时要传入日期格式模板

//构造方法:
public SimpleDateFormat(String pattern)

//转换:
public Date parse(String source)throws ParseException //-->此时取得的是全部时间数。

//格式化:
public final String Format(Date date)   //-->将时间重新格式化成字符串显示。

ⅲ. 示例

把Date转化成指定的日期格式

public class FormatDateTime {

     public static void main(String[] args) {
         SimpleDateFormat myFmt=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
         SimpleDateFormat myFmt1=new SimpleDateFormat("yy/MM/dd HH:mm"); 
         SimpleDateFormat myFmt2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//等价于now.toLocaleString()
         SimpleDateFormat myFmt3=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E ");
         SimpleDateFormat myFmt4=new SimpleDateFormat(
                 "一年中的第 D 天 一年中第w个星期 一月中第W个星期 在一天中k时 z时区");
         Date now=new Date();
         System.out.println(myFmt.format(now));
         System.out.println(myFmt1.format(now));
         System.out.println(myFmt2.format(now));
         System.out.println(myFmt3.format(now));
         System.out.println(myFmt4.format(now));
         System.out.println(now.toGMTString());
         System.out.println(now.toLocaleString());
         System.out.println(now.toString());
     }    

}

效果:

2023年12月16日 17时24分27秒
04/12/16 17:24
2023-12-16 17:24:27
2023年12月16日 17时24分27秒 星期四
一年中的第 351 天 一年中第51个星期 一月中第3个星期 在一天中17时 CST时区
16 Dec 2004 09:24:27 GMT
2023-12-16 17:24:27
Thu Dec 16 17:24:27 CST 2004

把给定的字符串中的日期提取为Date

这样做,通常是一个日期字符串,但不是想要的格式,可以先转化为Date,再转化为其它格式。

import java.text.* ;  
import java.util.* ;  
public class DateDemo05{  
    public static void main(String args[]){  
        String strDate = "2008-10-19 10:11:30.345" ;  
        // 准备第一个模板,从字符串中提取出日期数字  
        String pat1 = "yyyy-MM-dd HH:mm:ss.SSS" ;  
        // 准备第二个模板,将提取后的日期数字变为指定的格式  
        String pat2 = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒" ;  
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1) ;        // 实例化模板对象  
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2) ;        // 实例化模板对象  
        Date d = null ;  
        try{  
            d = sdf1.parse(strDate) ;   // 将给定的字符串中的日期提取出来  
        }catch(Exception e){            // 如果提供的字符串格式有错误,则进行异常处理  
            e.printStackTrace() ;       // 打印异常信息  
        }  
        System.out.println(sdf2.format(d)) ;    // 将日期变为新的格式  
    }  
};

c. DateFormat 和SimpleDateFormat 的区别

  1. DateFormat 可以直接使用,但其本身是一个抽象类,可以根据Locate指定的区域得到对应的日期时间格式
  2. SimpleDateFormat 类是DateFormat 类的子类,一般情况下来讲 DateFormat 类很少会直接使用。
    而都使用SimpleDateFormat 类完成。

d. 演示示例

ⅰ. 使用Date类获取时间的信息
/**
    目标:学会使用Date类处理时间,获取时间的信息
 */
public class DateDemo {
    public static void main(String[] args) {
        // 1、创建一个Date类的对象:代表系统此刻日期时间对象
        Date d = new Date();
        System.out.println(d);

        // 2、获取时间毫秒值
        long time = d.getTime();
        System.out.println(time);
//        long time1 = System.currentTimeMillis();
//        System.out.println(time1);

        System.out.println("----------------------------");
        // 1、得到当前时间
        Date d1 = new Date();
        System.out.println(d1);

        // 2、当前时间往后走 1小时  121s
        long time2 = System.currentTimeMillis();
        time2 += (60 * 60 + 121) * 1000;

        // 3、把时间毫秒值转换成对应的日期对象。
        // Date d2 = new Date(time2);
        // System.out.println(d2);

        Date d3 = new Date();
        d3.setTime(time2);
        System.out.println(d3);

    }
}
ⅱ. SimpleDateFormat简单日期格式化类的使用
package com.zheng.d12_simpledateformat;


import java.text.SimpleDateFormat;
import java.util.Date;

/**
    目标:SimpleDateFormat简单日期格式化类的使用
    格式化时间
    解析时间

 */
public class SimpleDateFormatDemo01 {
    public static void main(String[] args) {
        // 1、日期对象
        Date d = new Date();
        System.out.println(d);

        // 2、格式化这个日期对象 (指定最终格式化的形式)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
        // 3、开始格式化日期对象成为喜欢的字符串形式
        String rs = sdf.format(d);
        System.out.println(rs);

        System.out.println("----------------------------");

        // 4、格式化时间毫秒值
        // 需求:请问121秒后的时间是多少
        long time1 = System.currentTimeMillis() + 121 * 1000;
        String rs2 = sdf.format(time1);
        System.out.println(rs2);

        System.out.println("------------解析字符串时间,下个代码---------------");
    }
}
ⅲ. 使用SimpleDateFormat解析字符串时间成为日期对象
package com.zheng.d12_simpledateformat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatDemo2 {
    public static void main(String[] args) throws ParseException {
        // 目标: 学会使用SimpleDateFormat解析字符串时间成为日期对象。
        // 有一个时间 2021年08月06日 11:11:11 往后 2天 14小时 49分 06秒后的时间是多少。
        // 1、把字符串时间拿到程序中来
        String dateStr = "2021年08月06日 11:11:11";

        // 2、把字符串时间解析成日期对象(本节的重点):形式必须与被解析时间的形式完全一样,否则运行时解析报错!
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date d = sdf.parse(dateStr);

        // 3、往后走2天 14小时 49分 06秒
        long time = d.getTime() + (2L*24*60*60 + 14*60*60 + 49*60 + 6) * 1000;

        // 4、格式化这个时间毫秒值就是结果
        System.out.println(sdf.format(time));
    }
}
ⅳ. 秒杀案例
public class SimpleDateFormatTest3 {
    public static void main(String[] args) throws ParseException {
        // 1、开始 和 结束时间
        String startTime = "2021-11-11 00:00:00";
        String endTime = "2021-11-11 00:10:00";

        // 2、小贾 小皮
        String xiaoJia =  "2021-11-11 00:03:47";
        String xiaoPi =  "2021-11-11 00:10:11";

        // 3、解析他们的时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = sdf.parse(startTime);
        Date d2 = sdf.parse(endTime);
        Date d3 = sdf.parse(xiaoJia);
        Date d4 = sdf.parse(xiaoPi);

        if(d3.after(d1) && d3.before(d2)){
            System.out.println("小贾秒杀成功,可以发货了!");
        }else {
            System.out.println("小贾秒杀失败!");
        }

        if(d4.after(d1) && d4.before(d2)){
            System.out.println("小皮秒杀成功,可以发货了!");
        }else {
            System.out.println("小皮秒杀失败!");
        }
    }
}
ⅴ. String转换成Date对象

题目:请使用日期时间相关的API,计算出一个人已经出生了多少天。

思路:

① 获取当前时间对应的毫秒值

② 获取自己出生日期对应的毫秒值

③ 两个时间相减(当前时间– 出生日期)

代码实现:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/*
 把String转换成Date对象
*/
public class Demo {
    public static void main(String[] args) throws ParseException {
        System.out.println("请输入出生日期 格式 YYYY-MM-dd");
        // 获取出生日期,键盘输入
        String birthdayString = new Scanner(System.in).next();
        // 将字符串日期,转成Date对象
        // 创建SimpleDateFormat对象,写日期模式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 调用方法parse,字符串转成日期对象
        Date birthdayDate = sdf.parse(birthdayString);
        // 获取今天的日期对象
        Date todayDate = new Date();
        // 将两个日期转成毫秒值,Date类的方法getTime
        long birthdaySecond = birthdayDate.getTime();
        long todaySecond = todayDate.getTime();
        long secone = todaySecond-birthdaySecond;
        if (secone < 0){
            System.out.println("还没出生呢");
        } else {
            System.out.println(secone/1000/60/60/24);
        }
    }
}
请输入出生日期 格式 YYYY-MM-dd
2023-02-10
373

二、第二代日期类(Calendar)

1. 简介

java.util.Calendar是日历类,是一个抽象类,在Date后出现,替换掉了许多Date的方法。

该类将所有可能用到的时间信息封装为静态成员变量,方便获取。日历类就是方便获取各个时间属性的。

2. 演示示例

a. 日历类 Calendar

package com.zheng.d13_calendar;

import java.util.Calendar;
import java.util.Date;

/**
    目标:日历类Calendar的使用,可以得到更加丰富的信息。

    Calendar代表了系统此刻日期对应的日历对象。
    Calendar是一个抽象类,不能直接创建对象。
    Calendar日历类创建日历对象的语法:
        Calendar rightNow = Calendar.getInstance();
    Calendar的方法:
        1.public static Calendar getInstance(): 返回一个日历类的对象。
        2.public int get(int field):取日期中的某个字段信息。
        3.public void set(int field,int value):修改日历的某个字段信息。
        4.public void add(int field,int amount):为某个字段增加/减少指定的值
        5.public final Date getTime(): 拿到此刻日期对象。
        6.public long getTimeInMillis(): 拿到此刻时间毫秒值
    小结:
        记住。
 */
public class CalendarDemo{
    public static void main(String[] args) {
        // 1、拿到系统此刻日历对象
        Calendar cal = Calendar.getInstance();
        System.out.println(cal);

        // 2、获取日历的信息:public int get(int field):取日期中的某个字段信息。
        int year = cal.get(Calendar.YEAR);
        System.out.println(year);

        int mm = cal.get(Calendar.MONTH) + 1;
        System.out.println(mm);

        int days = cal.get(Calendar.DAY_OF_YEAR) ;
        System.out.println(days);

        // 3、public void set(int field,int value):修改日历的某个字段信息。
        // cal.set(Calendar.HOUR , 12);
        // System.out.println(cal);

        // 4.public void add(int field,int amount):为某个字段增加/减少指定的值
        // 请问64天后是什么时间
        cal.add(Calendar.DAY_OF_YEAR , 64);
        cal.add(Calendar.MINUTE , 59);

        //  5.public final Date getTime(): 拿到此刻日期对象。
        Date d = cal.getTime();
        System.out.println(d);

        //  6.public long getTimeInMillis(): 拿到此刻时间毫秒值
        long time = cal.getTimeInMillis();
        System.out.println(time);

    }
}

结果:

java.util.GregorianCalendar[time=1693714170215,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2023,MONTH=8,WEEK_OF_YEAR=36,WEEK_OF_MONTH=2,DAY_OF_MONTH=3,DAY_OF_YEAR=246,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=9,SECOND=30,MILLISECOND=215,ZONE_OFFSET=28800000,DST_OFFSET=0]
2023
9
246
Mon Nov 06 13:08:30 CST 2023
1699247310215

三、第三代日期类(JDK8新特性)

1. 前面两代缺点

a. 设计很差

在 java.util 和 java.sql 的包中都有日期类,java.util.Date同时包含日期和时间,

而java.sql.Date仅包含日期,此外用于格式化和解析的类在java.text包中定义。

b. 非线程安全

java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。

c. 时区处理麻烦

日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样

存在上述所有的问题。

2. 演示示例

package com.zheng.d7_newdatetimeapi;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo01 {
    public static void main(String[] args) {
        // 旧版日期时间 API 存在的问题
        // 1.设计不合理
        Date now = new Date(1985, 9, 23);
        System.out.println(now);

        // 2.时间格式化和解析是线程不安全的
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 50; i++) {
            new Thread(() -> {
                try {
                    Date date = sdf.parse("2023-08-09");
                    System.out.println("date = " + date);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

3. 新增日期时间 API

Java 8开始, java.time包下增加了一套全新的日期时间API,这套API设计合理,是线程安全的。

新的日期及时间API位于 java.time 包 中,下面是一些关键类。

  • LocalDate:表示日期,包含年月日,格式为 2019-10-16
  • LocalTime:表示时间,包含时分秒,格式为 16:38:54.158549300
  • LocalDateTime:表示日期时间,包含年月日,时分秒,格式为 2018-09-06T15:33:56.750
  • DateTimeFormatter:日期时间格式化类。
  • Instant:时间戳,表示一个特定的时间瞬间。
  • Duration:用于计算2个时间(LocalTime,时分秒)的距离
  • Period:用于计算2个日期(LocalDate,年月日)的距离
  • ZonedDateTime:包含时区的时间

Java中使用的历法是ISO 8601日历系统,它是世界民用历法,也就是我们所说的公历。

平年有365天,闰年是366天。

此外Java 8还提供了4套其他历法,分别是:

  • ThaiBuddhistDate:泰国佛教历
  • MinguoDate:中华民国历
  • JapaneseDate:日本历
  • HijrahDate:伊斯兰历

新增的API严格区分了时刻、本地日期、本地时间,并且,对日期和时间进行运算更加方便,

其次, 新API的类型几乎全部是不可变类型(与String的使用类似),可放心使用而不必担心被修改

4. JDK 8的日期和时间类

a. LocalDate & LocalTime & LocalDateTime

LocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、

时 间、日期和时间。

它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。

package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class ss {
    // LocalDate:获取日期时间的信息。格式为 2019-10-16
    @Test
    public void test01() {
        // 创建指定日期
        LocalDate fj = LocalDate.of(1985, 9, 23);
        System.out.println("fj = " + fj); // 1985-09-23

        // 得到当前日期
        LocalDate nowDate = LocalDate.now();
        System.out.println("nowDate = " + nowDate); // 2019-10-16


        // 获取日期信息
        System.out.println("年: " + nowDate.getYear());
        System.out.println("月: " + nowDate.getMonthValue());
        System.out.println("日: " + nowDate.getDayOfMonth());
        System.out.println("星期: " + nowDate.getDayOfWeek());
    }

    // LocalTime类: 获取时间信息。格式为 16:38:54.158549300
    @Test
    public void test02() {
        // 得到指定的时间
        LocalTime time = LocalTime.of(12,15, 28, 129_900_000);
        System.out.println("time = " + time);

        // 得到当前时间
        LocalTime nowTime = LocalTime.now();
        System.out.println("nowTime = " + nowTime);

        // 获取时间信息
        System.out.println("小时: " + nowTime.getHour());
        System.out.println("分钟: " + nowTime.getMinute());
        System.out.println("秒: " + nowTime.getSecond());
        System.out.println("纳秒: " + nowTime.getNano());
    }

    // LocalDateTime类: 获取日期时间信息。格式为 2018-09-06T15:33:56.750
    @Test
    public void test03() {
        LocalDateTime fj = LocalDateTime.of(1985, 9, 23, 9, 10, 20);
        System.out.println("fj = " + fj); // 1985-09-23T09:10:20

        // 得到当前日期时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now = " + now); // 2019-10-16T16:42:24.497896800

        System.out.println(now.getYear());
        System.out.println(now.getMonthValue());
        System.out.println(now.getDayOfMonth());
        System.out.println(now.getHour());
        System.out.println(now.getMinute());
        System.out.println(now.getSecond());
        System.out.println(now.getNano());
    }
}

结果:

fj = 1985-09-23T09:10:20
now = 2023-09-03T12:23:41.261714100
2023
9
3
12
23
41
261714100
ⅰ. 日期时间修改

对日期时间的修改,对已存在的LocalDate对象,创建它的修改版,最简单的方式是使用withAttribute方法。

withAttribute方法会创建对象的一个副本,并按照需要修改它的属性。

以下所有的方法都返回了一个修改属性的对 象,他们不会影响原来的对象。

package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.LocalDateTime;

public class ss {
    // LocalDateTime类: 对日期时间的修改
    @Test
    public void test05() {
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now = " + now);

        // 修改日期时间
        LocalDateTime setYear = now.withYear(2078);
        System.out.println("修改年份: " + setYear);
        System.out.println("now == setYear: " + (now == setYear));

        System.out.println("修改月份: " + now.withMonth(6));
        System.out.println("修改小时: " + now.withHour(9));
        System.out.println("修改分钟: " + now.withMinute(11));


        // 再当前对象的基础上加上或减去指定的时间
        LocalDateTime localDateTime = now.plusDays(5);
        System.out.println("5天后: " + localDateTime);
        System.out.println("now == localDateTime: " + (now == localDateTime));
        System.out.println("10年后: " + now.plusYears(10));
        System.out.println("20月后: " + now.plusMonths(20));

        System.out.println("20年前: " + now.minusYears(20));
        System.out.println("5月前: " + now.minusMonths(5));
        System.out.println("100天前: " + now.minusDays(100));
    }

}
ⅱ. 日期时间的比较
package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.LocalDate;

public class ss {
    // 日期时间的比较 
    @Test
    public void test06() {
        // 在JDK8中,LocalDate类中使用isBefore()、isAfter()、equals()方法来比较两个日期,可直接进行比较。 
        LocalDate now = LocalDate.now();
        LocalDate date = LocalDate.of(2018, 8, 8);

        System.out.println(now.isBefore(date)); // false 
        System.out.println(now.isAfter(date)); // true 
    }
    
}

b. DateTimeFormatter(时间格式化与解析)

DateTimeFormatter:日期时间格式化类。

通过 java.time.format.DateTimeFormatter 类可以进行日期时间解析与格式化。

package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class ss {
    // 日期格式化 
    @Test
    public void test04() {
        // 得到当前日期时间 
        LocalDateTime now = LocalDateTime.now();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 将日期时间格式化为字符串 
        String format = now.format(formatter);
        System.out.println("format = " + format);

        // 将字符串解析为日期时间 
        LocalDateTime parse = LocalDateTime.parse("1985-09-23 10:12:22", formatter);
        System.out.println("parse = " + parse);
    }

}

c. Instant(时间戳)

Instant:时间戳,表示一个特定的时间瞬间,格式:2019-10-19T07:30:42.629520400Z

Instant 时间戳/时间线,内部保存了从1970年1月1日 00:00:00以来的秒和纳秒。

package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.Instant;

public class ss {
    // 时间戳 
    @Test
    public void test07() {
        Instant now = Instant.now();
        System.out.println("当前时间戳 = " + now);
        // 获取从1970年1月1日 00:00:00的秒 
        System.out.println(now.getNano());
        System.out.println(now.getEpochSecond());
        System.out.println(now.toEpochMilli());
        System.out.println(System.currentTimeMillis());

        Instant instant = Instant.ofEpochSecond(5);
        System.out.println(instant);
    }

}

d. Duration/Period(计算日期时间差类)

Duration/Period类: 计算日期时间差。

  1. Duration:用于计算2个时间(LocalTime,时分秒)的距离
  2. Period:用于计算2个日期(LocalDate,年月日)的距离
package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.*;

public class ss {
    // Duration/Period类: 计算日期时间差 
    @Test
    public void test08() {
        // Duration计算时间的距离 
        LocalTime now = LocalTime.now();
        LocalTime time = LocalTime.of(14, 15, 20);
        Duration duration = Duration.between(time, now);
        System.out.println("相差的天数:" + duration.toDays());
        System.out.println("相差的小时数:" + duration.toHours());
        System.out.println("相差的分钟数:" + duration.toMinutes());
        System.out.println("相差的秒数:" + duration.toSeconds());

        // Period计算日期的距离 
        LocalDate nowDate = LocalDate.now();
        LocalDate date = LocalDate.of(1998, 8, 8);
        // 让后面的时间减去前面的时间 
        Period period = Period.between(date, nowDate);
        System.out.println("相差的年:" + period.getYears());
        System.out.println("相差的月:" + period.getMonths());
        System.out.println("相差的天:" + period.getDays());
    }
}

e. TemporalAdjuster & TemporalAdjusters(时间校正器)

有时我们可能需要获取例如:将日期调整到“下一个月的第一天”等操作。可以通过时间校正器来进行。

  • TemporalAdjuster : 时间校正器
  • TemporalAdjusters : 该类通过静态方法提供了大量的常用TemporalAdjuster的实现
package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.*;
import java.time.temporal.TemporalAdjuster;

public class ss {
    // TemporalAdjuster类:自定义调整时间 
    @Test
    public void test09() {
        LocalDateTime now = LocalDateTime.now();

        // 得到下一个月的第一天 
        TemporalAdjuster firsWeekDayOfNextMonth = temporal -> {
            LocalDateTime dateTime = (LocalDateTime) temporal;
            LocalDateTime nextMonth = dateTime.plusMonths(1).withDayOfMonth(1);
            System.out.println("nextMonth = " + nextMonth);
            return nextMonth;
        };

        LocalDateTime nextMonth = now.with(firsWeekDayOfNextMonth);
        System.out.println("nextMonth = " + nextMonth);
    }

}

f. 设置日期时间的时区

Java8 中加入了对时区的支持,LocalDate、LocalTime、LocalDateTime是不带时区的,

带时区的日期时间类分别 为:ZonedDate、ZonedTime、ZonedDateTime。

其中每个时区都对应着 ID,ID的格式为 “区域/城市” 。

例如 :Asia/Shanghai 等。ZoneId:该类中包含了所有的时区信息。

package com.zheng.d7_newdatetimeapi;

import org.junit.Test;

import java.time.*;

public class ss {
    // 设置日期时间的时区
    @Test
    public void test10() {
        // 1.获取所有的时区ID
        // ZoneId.getAvailableZoneIds().forEach(System.out::println);

        // 不带时间,获取计算机的当前时间
        LocalDateTime now = LocalDateTime.now(); // 中国使用的东八区的时区.比标准时间早8个小时
        System.out.println("now = " + now);

        // 2.操作带时区的类
        // now(Clock.systemUTC()): 创建世界标准时间
        ZonedDateTime bz = ZonedDateTime.now(Clock.systemUTC());
        System.out.println("bz = " + bz);

        // now(): 使用计算机的默认的时区,创建日期时间
        ZonedDateTime now1 = ZonedDateTime.now();
        System.out.println("now1 = " + now1); // 2019-10-19T16:19:44.007153500+08:00[Asia/Shanghai]

        // 使用指定的时区创建日期时间
        ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("America/Vancouver"));
        System.out.println("now2 = " + now2); // 2019-10-19T01:21:44.248794200-07:00[America/Vancouver]
    }

}

g. 总结

新的日期是时间相关类:

  1. LocalDate表示日期,包含年月日,LocalTime表示时间,包含时分 秒,LocalDateTime = LocalDate + LocalTime,
  2. 时间的格式化和解析,通过DateTimeFormatter类型进行.
  3. Instant类,方便操作秒和纳秒,一般是给程序使用的
  4. Duration/Period计算日期或时间的距离,还使用时间调 整器方便的调整时间,
  5. 带时区的3个类ZoneDate/ZoneTime/ZoneDateTime

JDK 8新的日期和时间 API的优势:

  1. 新版的日期和时间API中,日期和时间对象是不可变的。操纵的日期不会影响老值,而是新生成一个实例。
  2. 新的API提供了两种不同的时间表示方式,有效地区分了人和机器的不同需求。
  3. TemporalAdjuster可以更精确的操纵日期,还可以自定义日期调整器。
  4. 是线程安全的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wclass-zhengge

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

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

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

打赏作者

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

抵扣说明:

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

余额充值