Java日期时间使用总结

一、Java中的日期概述

日期在Java中是一块非常复杂的内容,对于一个日期在不同的语言、国别环境中,日期的国际化、日期和时间之间转换、日期的加减运算、日期的展示格式都是非常复杂的问题。

在Java中,操作日期主要涉及到以下几个类:

1、java.util.Date

Date 类表示特定的瞬间,精确到毫秒。从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和分析日期字符串。Date 中的把日期解释为年、月、日、时、分、秒的方法已经废弃了。

2、java.text.DateFormat (抽象类)

DateFormat 是日期 / 时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。日期 / 时间格式化子类(如SimpleDateFormat )允许进行格式化(也就是日期 -> 文本)、分析(文本 -> 日期)、和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年 01 月 01 日 00:00:00 这一刻开始的毫秒数。

3、java.text.SimpleDateFormat (DateFormat 的直接子类)

SimpleDateFormat 是一个以语言环境相关的方式来格式化和分析日期的具体类。它允许进行格式化(日期 -> 文本)、分析(文本 -> 日期)、和规范化。
SimpleDateFormat 可以选择任何用户定义的日期 - 时间格式的模式。但是,仍然建议通过 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 来创建日期 - 时间格式化程序。

4、java.util.Calendar(抽象类)

Calendar 类是一个抽象类,它是特定瞬间与一组诸如:YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下个星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(格林威治标准时间 1970 年 01 月 01 日的 00:00:00.000,格里高利历)的偏移量。
与其他语言环境敏感类一样,Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。
Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化。

5、java.util.GregorianCalendar (Calendar 的直接子类)

GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家使用的标准日历系统。
GregorianCalendar 是一种混合日历,在单一间断性的支持下同时支持儒略历和格里高利历系统,在默认情况下,它对应格里高利日历创立时的格里高利历日期(某些国家是在 1582 年 10 月 15 日创立,在其他国家要晚一些)。可由调用方通过调用 setGregorianChange() 来更改起始日期。

二、Java中的日期使用

1、java.util.Date

简介:类 java.util.Date 表示特定的瞬间,精确到毫秒。提供了很多的方法,但是很多已经过时,不推荐使用

方法摘要:
boolean after (Date when)—————测试此日期是否在指定日期之后。

boolean before (Date when)————测试此日期是否在指定日期之前。

Object clone () ——————————返回此对象的副本。

int compareTo (Date anotherDate)——比较两个日期的顺序。

boolean equals (Object obj)—————比较两个日期的相等性。

long getTime ()——————————返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。

int hashCode ()——————————返回此对象的哈希码值。

void setTime (long time)——————设置此 Date 对象,以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点。

String toString()——————————把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy
dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
mon 是月份 (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)。
dd 是一月中的某一天(01 至 31),显示为两位十进制数。
hh 是一天中的小时(00 至 23),显示为两位十进制数。
mm 是小时中的分钟(00 至 59),显示为两位十进制数。
ss 是分钟中的秒数(00 至 61),显示为两位十进制数。
zzz 是时区(并可以反映夏令时)。标准时区缩写包括方法 parse 识别的时区缩写。如果不提供时区信息,则 zzz 为空。
yyyy 是年份,显示为 4 位十进制数。

例:

import java.util.Date;

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-30
* Time: 8:45:44
* 日期测试
*/
public class TestDate {
public static void main(String args[]) {
TestDate nowDate = new TestDate();
nowDate.getSystemCurrentTime();
nowDate.getCurrentDate();
}

/**
* 获取系统当前时间
* System.currentTimeMillis()返回系统当前时间,结果为1970年1月1日0时0分0秒开始,到程序执行取得系统时间为止所经过的毫秒数
* 1秒=1000毫秒
*/
public void getSystemCurrentTime() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowTime = formatter.format(date);
System.out.println("----获取系统当前时间----");
System.out.println("系统当前时间 = " + System.currentTimeMillis());
}

/**
* 通过Date类获取当前日期和当前时间
* date.toString()把日期转换为dow mon dd hh:mm:ss zzz yyyy
*/
public void getCurrentDate() {
System.out.println("----获取系统当前日期----");
//创建并初始化一个日期(初始值为当前日期)
Date date = new Date();
System.out.println("现在的日期是 = " + date.toString());
System.out.println("自1970年1月1日0时0分0秒开始至今所经历的毫秒数 = " + date.getTime());
}
}

运行结果:

----获取系统当前时间----
系统当前时间 = 1196413077278
----获取系统当前日期----
现在的日期是 = Fri Nov 30 16:57:57 CST 2007197011000秒开始至今所经历的毫秒数 = 1196413077278

Process finished with exit code 0

2、java.text.DateFormat 抽象类的使用

DateFormat 提供了很多类方法,以获得基于默认或给定语言环境和多种格式化风格的默认日期 / 时间。
DateFormat 可以帮助进行格式化并分析任何语言环境的日期。对于月、星期,甚至日历格式(阴历和阳历)

如果格式化多个日期,那么获得该格式并多次使用它是更为高效的做法,这样系统就不必多次获取有关环境语言和国家约定的信息了。

DateFormat df = DateFormat.getDateInstance();
for (int i = 0; i < myDate.length; ++i) {
	output.println(df.format(myDate[i]) + "; ");
}

要格式化不同语言环境的日期,可在 getDateInstance() 的调用中指定它。

DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);

还可使用 DateFormat 进行分析。

myDate = df.parse(myString);

DateFormat 不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须保持外部同步。

3、java.text.SimpleDateFormat(DateFormat 的直接子类)的使用

SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。

日期和时间格式由日期和时间模式 字符串指定。
G Era 标志符 Text AD
y 年 Year 1996; 96
M 年中的月份 Month July; Jul; 07
w 年中的周数 Number 27
W 月份中的周数 Number 2
D 年中的天数 Number 189
d 月份中的天数 Number 10
F 月份中的星期 Number 2
E 星期中的天数 Text Tuesday; Tue
a Am/pm 标记 Text PM
H 一天中的小时数(0-23) Number 0
k 一天中的小时数(1-24) Number 24
K am/pm 中的小时数(0-11) Number 0
h am/pm 中的小时数(1-12) Number 12
m 小时中的分钟数 Number 30
s 分钟中的秒数 Number 55
S 毫秒数 Number 978
z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
Z 时区 RFC 822 time zone -0800
更多的参考信息可以查看JDK API文档

例:

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

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-30
* Time: 11:20:58
* To change this template use File | Settings | File Templates.
*/
public class TestSimpleDateFormat {
public static void main(String args[]) throws ParseException {
TestSimpleDateFormat test = new TestSimpleDateFormat();
test.testDateFormat();

}

public void testDateFormat() throws ParseException {
//创建日期
Date date = new Date();

//创建不同的日期格式
DateFormat df1 = DateFormat.getInstance();
DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss EE");
DateFormat df3 = DateFormat.getDateInstance(DateFormat.FULL, Locale.CHINA); //产生一个指定国家指定长度的日期格式,长度不同,显示的日期完整性也不同
DateFormat df4 = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒 EE", Locale.CHINA);
DateFormat df5 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss EEEEEE", Locale.US);
DateFormat df6 = new SimpleDateFormat("yyyy-MM-dd");
DateFormat df7 = new SimpleDateFormat("yyyy年MM月dd日");

//将日期按照不同格式进行输出
System.out.println("-------将日期按照不同格式进行输出------");
System.out.println("按照Java默认的日期格式,默认的区域 : " + df1.format(date));
System.out.println("按照指定格式 yyyy-MM-dd hh:mm:ss EE ,系统默认区域 :" + df2.format(date));
System.out.println("按照日期的FULL模式,区域设置为中文 : " + df3.format(date));
System.out.println("按照指定格式 yyyy年MM月dd日 hh时mm分ss秒 EE ,区域为中文 : " + df4.format(date));
System.out.println("按照指定格式 yyyy-MM-dd hh:mm:ss EE ,区域为美国 : " + df5.format(date));
System.out.println("按照指定格式 yyyy-MM-dd ,系统默认区域 : " + df6.format(date));

//将符合该格式的字符串转换为日期,若格式不相配,则会出错
Date date1 = df1.parse("07-11-30 下午2:32");
Date date2 = df2.parse("2007-11-30 02:51:07 星期五");
Date date3 = df3.parse("2007年11月30日 星期五");
Date date4 = df4.parse("2007年11月30日 02时51分18秒 星期五");
Date date5 = df5.parse("2007-11-30 02:51:18 Friday");
Date date6 = df6.parse("2007-11-30");

System.out.println("-------输出将字符串转换为日期的结果------");
System.out.println(date1);
System.out.println(date2);
System.out.println(date3);
System.out.println(date4);
System.out.println(date5);
System.out.println(date6);
}
}

运行结果:

-------将日期按照不同格式进行输出------
按照Java默认的日期格式,默认的区域 : 07-11-30 下午5:04
按照指定格式 yyyy-MM-dd hh:mm:ss EE ,系统默认区域 :2007-11-30 05:04:10 星期五
按照日期的FULL模式,区域设置为中文 : 20071130日 星期五
按照指定格式 yyyy年MM月dd日 hh时mm分ss秒 EE ,区域为中文 : 20071130050410秒 星期五
按照指定格式 yyyy-MM-dd hh:mm:ss EE ,区域为美国 : 2007-11-30 05:04:10 Friday
按照指定格式 yyyy-MM-dd ,系统默认区域 : 2007-11-30
-------输出将字符串转换为日期的结果------
Fri Nov 30 14:32:00 CST 2007
Fri Nov 30 02:51:07 CST 2007
Fri Nov 30 00:00:00 CST 2007
Fri Nov 30 02:51:18 CST 2007
Fri Nov 30 02:51:18 CST 2007
Fri Nov 30 00:00:00 CST 2007

Process finished with exit code 0

4、java.util.Calendar(抽象类)

一个 Calendar 的实例是系统时间的抽象表示,从 Calendar 的实例可以知道年、月、日、星期、月份、时区等信息。
Calendar 类中有一个静态方法 get(int x),通过这个方法可以获取到相关实例的一些值(年月日)信息。

Calendar 中的一些陷阱,很容易掉下去:
1、Calendar 的星期是从周日开始的,常量值为0。
2、Calendar 的月份是从一月开始的,常量值为0。
3、Calendar 的每个月的第一天值为1。

5、java.util.GregorianCalendar(Calendar 的直接子类)

GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家使用的标准日历系统。结合Calendar抽象类使用。

例:

import java.util.*;
import java.text.SimpleDateFormat;

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-30
* Time: 15:06:57
* Calendar的使用测试
*/
public class TestCalendar {
public static void main(String args[]) {
TestCalendar testCalendar = new TestCalendar();
testCalendar.testCalendar();

}

public void testCalendar() {
//创建Calendar的方式
Calendar now1 = Calendar.getInstance();
Calendar now2 = new GregorianCalendar();
Calendar now3 = new GregorianCalendar(2007, 10, 30);
Calendar now4 = new GregorianCalendar(2007, 10, 30, 15, 55); //陷阱:Calendar的月份是0~11
Calendar now5 = new GregorianCalendar(2007, 10, 30, 15, 55, 44);
Calendar now6 = new GregorianCalendar(Locale.US);
Calendar now7 = new GregorianCalendar(TimeZone.getTimeZone("GMT-8:00"));

//通过日期和毫秒数设置Calendar
now2.setTime(new Date());
System.out.println(now2);

now2.setTimeInMillis(new Date().getTime());
System.out.println(now2);

//定义日期的中文输出格式,并输出日期
SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒 E", Locale.CHINA);
System.out.println("获取日期中文格式化化输出:" + df.format(now5.getTime()));
System.out.println();

System.out.println("--------通过Calendar获取日期中年月日等相关信息--------");
System.out.println("获取年:" + now5.get(Calendar.YEAR));
System.out.println("获取月(月份是从0开始的):" + now5.get(Calendar.MONTH));
System.out.println("获取日:" + now5.get(Calendar.DAY_OF_MONTH));
System.out.println("获取时:" + now5.get(Calendar.HOUR));
System.out.println("获取分:" + now5.get(Calendar.MINUTE));
System.out.println("获取秒:" + now5.get(Calendar.SECOND));
System.out.println("获取上午、下午:" + now5.get(Calendar.AM_PM));
System.out.println("获取星期数值(星期是从周日开始的):" + now5.get(Calendar.DAY_OF_WEEK));
System.out.println();

System.out.println("---------通用星期中文化转换---------");
String dayOfWeek[] = {"", "日", "一", "二", "三", "四", "五", "六"};
System.out.println("now5对象的星期是:" + dayOfWeek[now5.get(Calendar.DAY_OF_WEEK)]);
System.out.println();

System.out.println("---------通用月份中文化转换---------");
String months[] = {"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
System.out.println("now5对象的月份是: " + months[now5.get(Calendar.MONTH)]);
}
}

运行结果:

java.util.GregorianCalendar[time=1196414388324,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2007,MONTH=10,WEEK_OF_YEAR=48,WEEK_OF_MONTH=5,DAY_OF_MONTH=30,DAY_OF_YEAR=334,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=19,SECOND=48,MILLISECOND=324,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.util.GregorianCalendar[time=1196414388324,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2007,MONTH=10,WEEK_OF_YEAR=48,WEEK_OF_MONTH=5,DAY_OF_MONTH=30,DAY_OF_YEAR=334,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=19,SECOND=48,MILLISECOND=324,ZONE_OFFSET=28800000,DST_OFFSET=0]
获取日期中文格式化化输出:20071130035544秒 星期五

--------通过Calendar获取日期中年月日等相关信息--------
获取年:2007
获取月(月份是从0开始的)10
获取日:30
获取时:3
获取分:55
获取秒:44
获取上午、下午:1
获取星期数值(星期是从周日开始的)6

---------通用星期中文化转换---------
now5对象的星期是:---------通用月份中文化转换---------
now5对象的月份是: 十一月

Process finished with exit code 0

6、Date/Time API

1、LocalDate
LocalDate 只是一个日期,没有时间。这意味着我们只能获得当前日期,但没有当天的具体时间。

LocalDate date = LocalDate.now(); // get the current date 

我们可以 format 它

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");  
System.out.println(date.format(formatter));  

得到的结果只有年月日:

25-11-2018 

2、LocalTime
LocalTime 与 LocalDate 相反,它只代表一个时间,没有日期。这意味着我们只能获得当天的当前时间,而没有实际日期:

LocalTime time = LocalTime.now(); // get the current time  

可以按如下方式 format

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");  
System.out.println(time.format(formatter)); 

得到结果类似如下:

00:55:58  

3、LocalDateTime
最后一个是 LocalDateTime,也是 Java 中最常用的 Date/Time 类,代表前两个类的组合 - 即日期和时间的值:

LocalDateTime dateTime = LocalDateTime.now(); // get the current date and time  

format 的方式也一样

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");  
System.out.println(dateTime.format(formatter));  

得到的日期结果类似于:

25-11-2018 00:57:20  

7、Java 中 Date 日期格式的各种转换

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

public class DateParserT {

    /**
     * Date 与 String、Long、LocalDate 的互相转换
     * @param args
     */
    public static void main(String[] args) {

        Date date = new Date();
        //格式:Tue Sep 22 14:11:02 CST 2020
        System.out.println("date格式:" + date);

        //格式:2020年9月22日 星期二
        String formatDate = null;
        formatDate = DateFormat.getDateInstance(DateFormat.FULL).format(date);
        System.out.println("formatDate格式:" + formatDate);


        //格式 Long <---> Date 类型,再转换成 String 
        //类型:1600755803 <---> 2020-09-22 14:23:23
		//String -> Date
        long longTime = 1600755803L;
        Date date =new Date(System.currentTimeMillis());

		//Date -> String
        Date date = new  Date();
        Long temp = date.getTime();
 

        //格式 String <---> Date 
        //类型:2020-09-22 14:23:23 <---> Tue Sep 22 14:23:23 CST 2020
        //String -> Date
        String sDate = "2020-09-22 14:23:23";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date strD = sdf.parse(sDate);
            System.out.println("sreD格式:" + strD);
        }catch (ParseException e){
            e.getErrorOffset();
        }

		//Date -> String
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String s = sdf.format(new Date);
        //s = Mon Jun 20 23:11:59 CST 2022


		//格式 String <---> LocalDate 
		//类型:2020-09-22 14:23:23 <---> Tue Sep 22 14:23:23 CST 2020
        //String -> LocalDateTime
		String timeStr = "2022/6/20"
		LocalDate parse = LocalDate.parse(timeStr, 
    	DateTimeFormatter.ofPattern("yyyy/M/dd"));
    	
		//LocalDateTime -> String
		LocalDateTime now = LocalDateTime.now();
        //s = 2022-06-20T18:42:35.332
        String s = now.toString();

    }
}

运行结果

date格式:Tue Sep 22 14:33:22 CST 2020
formatDate格式:2020922日 星期二
sreD格式:Tue Sep 22 14:23:23 CST 2020

Process finished with exit code 0

8、LocalDate 日期比较大小

/**
 * 比较第一个日期是否小于第二个日期
 * @param firstDate 第一个日期
 * @param secondDate 第二个日期
 * @return true-小于;false-大于
 */
public boolean localDateIsBefore(LocalDate firstDate, LocalDate secondDate) {
	return firstDate.isBefore(secondDate);
}
 
 
/**
 * 比较第一个日期是否大于第二个日期
 * @param firstDate 第一个日期
 * @param secondDate 第二个日期
 * @return true-大于;false-不大于
 */
public boolean localDateIsAfter(LocalDate firstDate, LocalDate secondDate) {
	return firstDate.isAfter(secondDate);
}
 
/**
 * 比较两个日期是否相等
 * @param firstDate 第一个日期
 * @param secondDate 第二个日期
 * @return true-相等;false-不相等
 */
public boolean localDateIsEqual(LocalDate firstDate, LocalDate secondDate) {
	return firstDate.isEqual(secondDate);
}

9、Date 日期比较大小

String beginTime = "2018-07-28 14:42:32";
String endTime = "2018-07-29 12:26:32";
 
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
try {
	Date date1 = format.parse(beginTime);
	Date date2 = format.parse(endTime);
	
	//方法一:compareTo()方法的返回值,date1小于date2返回-1,date1大于date2返回1,相等返回0
	int compareTo = date1.compareTo(date2);
	
	//方法二:before()在...之前或者after()在...之后,方法的返回值为boolean类型
	boolean before = date1.before(date2);
	
} catch (ParseException e) {
	e.printStackTrace();
}

三、时间日期计算

1、LocalDate、LocalDateTime 计算时间差

	DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	LocalDateTime now = LocalDateTime.parse("2021-12-21 00:00:00", dtf);
	LocalDateTime end = LocalDateTime.parse("2022-03-21 23:59:59", dtf);
	
	//1.相差的天数
	long until = now.until(end, ChronoUnit.DAYS); 
	
	//2.相差的天数
	Duration duration = Duration.between(now,end);
	long days = duration.toDays(); 
	
	System.out.println(days);

2、LocalDate、LocalTime、LocalDateTime 类的使用

JDK1.7 存在的问题以及 JDK1.8 新特性:

  • JDK1.7 的问题
    在 JDK1.8 版本发布了新的 Date-Time API 来加强对时间、日期的处理,因为在 JDK1.7 中时间、日期的处理上存在如下的一些问题

    • 非现存安全:Date 类是非线程安全的,这是 Java 时间日期类中最大的问题
    • 设计很差:
      • 在 Java.util 包和 Java.sql 包下都有时间日期类 Date,java.util.Date 同时包含时间和日期,而 java.sql.Date 只包含日期。在不同的包设计了相似的功能,而且这两个类具有相同名字,是一种非常糟糕的设计
      • Date 类在 java.util 包下,而 Date 类的格式化和解析类 SimpleDateFormat 在 java.text 包下
      • 日期类不提供国际化,没有时区支持
  • JDK1.8 新特性
    为了解决上面的问题,JDK1.8 在java.time 包下提供了很多新的 API。

    • 新的 java.time 包涵盖了所有处理日期、时间、时区、时刻(instants)、过程(during)与时钟的操作。比较重要的两个API:Local(本地)和 Zoned(时区)
      • Local 简化了时间、日期的处理,没有时区问题
      • Zoned 通过制定的时区处理时间日期。

    我们在处理时间、日期的时候会常用的 3 个类,LocalDate、LocalTime、LocalDateTime,这三个类都是 final 类。这三个类的使用方法差不多,看懂一个类的使用,其他两个类和这个类的使用差不多。

LocalDate、LocalTime、LocalDateTime
创建对象
静态方法 now()
在创建 LocalDate、LocalTime、LocalDateTime 对象得时候,推荐使用实例方法 .now() 来实例化,now() 方法是获取当前日期和时机

	LocalDateTime currentTime = LocalDateTime.now();
	System.out.println(currentTime);
	// 2020-12-23T14:11:53.943
LocalDate 的方法
静态方法返回值说明
now()LocalDate根据当前时间创建 LocalDate 对象
of ( int year, int month, int dayOfMonth )LocalDate根据传递的年、月、日创建 LocalDate 对象
ofYearDay ( int year, int dayOfYear )LocalDate根据传递的年和天数 ( 相对该年1月1日的天数 ) 创建 LocalDate 对象
parse ( CharSequence text )LocalDate根据字符串 ( 仅 yyyy-MM-dd 形式 ) 创建 LocalDate 对象
parse ( CharSequence text, DateTimeFormatter formatter )LocalDate根据自定义格式字符串创建 LocalDate 对象
实例方法返回值说明
getYear()
lengthOfYear()
int获取当前日期的年份
获取当前年份有多少天
getMonth()
getMonthValue()
lengthOfMonth()
Month
int
int
获取当前日期月份 ( 英文全称 )
获取当前月份 ( 数字 )
获取当前月份有多少天
getDayOfWeek()
getDayOfMonth()
getDayOfYear()
DayOfWeek
int
int
获取当前日期是星期几 ( 星期的英文全称 )
获取当前日期是所在月份的第几天
获取当前日期是所在年份的第几天
withYear( int year )
withMonth( int month )
withDayOfMonth( int dayOfMonth )
withDayOfYear( int dayOfYear )
LocalDate用参数 year 修改年份
用参数 month 修改月份
用参数 dayOfMonth 修改所在月份的第几天
用参数 dayOfYear 修改所在年份的第几天
minusDays( long days )
minusWeeks( long weeks )
minusMonths( long months )
minusYears( long years )
LocalDate当前日期减 days 天
当前日期减 weeks 周
当前日期减 months 月
当前日期减 years 年
plusDays( long days )
plusWeeks( long weeks )
plusMonths( long months )
plusYears( long years )
LocalDate当前日期加 days 天
当前日期加 weeks 周
当前日期加 months 月
当前日期加 years 年
equals( Object obj )bolean检查这个日期是否等于另一个日期 obj
compareTo( ChronoLocalDate other )int比较这个日期和另一个日期 other 的大小,返回差值
atTime( int hour, int minute, int second )LocalDateTimeLocalDate 对象结合给出的时间生成一个 LocalDateTime 对象
isAfter( LocalDate other )bolean判断目前日期是否在 other 值后,是则返回 true,否则返回 false
isBefore( LocalDate other )bolean判断目前日期是否在 other 值前,是则返回 true,否则返回 false
LocalTime 的方法
静态方法返回值说明
now()LocalDateTime根据当前日期和时间创建 LocalDateTime 对象
of( int hour, int minute )
of( int hour, int minute, int second )
LocalTime根据时、分设置时间
根据时、分、秒设置时间
parse ( CharSequence text )LocalTime根据字符串 ( HH:mm:ss 形式 ) 创建 LocalTime 对象
parse ( CharSequence text, DateTimeFormatter formatter )LocalTime根据自定义格式字符串创建 LocalTime 对象
实例方法返回值说明
getHour()
getMinute()
getSecond()
int获取当前时间的小时数
获取当前时间的分钟数
获取当前时间的秒数
withHour( int hour )
withMinute( int minute )
withSecond( int second )
LocalTime用参数 hour 修改小时
用参数 minute 修改分钟
用参数 second 修改秒
minusHours( long hours )
minusMinutes( long minutes )
minusSeconds( long seconds )
LocalDate当前时间减 hours 小时
当前时间减 minutes 分钟
当前时间减 seconds 秒
plusHours( long hours )
plusMinutes( long minutes )
plusSeconds( long seconds )
LocalDate当前时间加 hours 小时
当前时间加 minutes 分钟
当前时间加 seconds 秒
atDate( LocalDate date )LocalDateTimeLocalTime 对象结合给出的 LocalDate 对象,生成一个 LocalDateTime 对象
isAfter( LocalTime other )bolean判断目前时间是否在 other 值后,是则返回 true,否则返回 false
isBefore( LocalTime other )bolean判断目前时间是否在 other 值前,是则返回 true,否则返回 false
LocalDateTime 的方法
静态方法返回值说明
now()LocalDateTime根据当前日期和时间创建 LocalDateTime 对象
of( LocalDate date, LocalTime time )LocalDateTime根据日期类对象 date 和时间类对象 time 创建 LocalDateTime 对象
parse( CharSequence text )LocalDateTime根据字符串 ( 仅 yyyy-MM-dd HH:mm:ss 形式 ) 创建 LocalDateTime 对象
parse( CharSequence text, DateTimeFormatter formatter )LocalDateTime根据自定义格式字符串创建 LocalDateTime 对象
isAfter( LocalDateTime other )boolean判断目前r日期时间是否在 other 值后,是则返回 true,否则返回 false
isBefore( LocalDateTime other )boolean判断目前r日期时间是否在 other 值前,是则返回 true,否则返回 false

实例方法:上面 LocalDate、LocalTime 提供的 get、with、minus、plus、equals、compareTo 这些方法在 LocalDateTime 中都有。一般来讲,用的较多的还是 LocalDateTime 类

DateTimeFormatter

用于 LocalDateTime、LocalDate、LocalTime 和字符串的转换

	// 字符串 ——> 日期时间类
	String dateTime = "2021-01-05 12:00:00";
	DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	LocalDateTime ldt = LocalDateTime.parse(dateTime, df);


	// 日期时间类 ——> 字符串
	LocalDateTime ldt = LocalDateTime.now();
	DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	String dateTime = ldt.format(df);
Duration

用于计算两个日期时间类对象的差值

	String dateTime1 = "2021-01-05 12:00:00";
	String dateTime2 = "2021-01-07 11:00:00";
	DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	LocalDateTime ldt1 = LocalDateTime.parse(dateTime1, df);
	LocalDateTime ldt2 = LocalDateTime.parse(dateTime2, df);
	System.out.println(ldt1.format(df));
	System.out.println(ldt2.format(df));
	
	Duration duration = Duration.between(ldt1, ldt2);
	Long days = duration.toDays();
	System.out.println(days);

除了转换成天数的方法还有转换小时、分钟等等的方法

  • toDays(): - long
  • toHours(): - long
  • toMillis(): - long
  • toMinutes(): - long
  • toNanos(): - long
  • toString(): - long
  • toDays(): - String

好事定律:每件事最后都会是好事,如果不是好事,说明还没到最后。