第十章《日期与时间》第1节:Date类的使用

时间:2022-12-31 16:59:37

​在JDK1.8之前,程序员都是用Date类的对象来表示日期时间。Date类位于java.util包下,各位读者需要特别注意:在java.sql包下有一个类也叫Date,所以大家在引入Date类的时候千万不要写错。虽然Date一词意为日期,但Date类的对象不仅仅能够表示出一个日期,还能表示出这个日期中的时间,这个时间可以精确到毫秒,因此Date类的对象本质上就代表了一个时间点,本小节就着重讲解Date类的使用方法。

10.1.1创建Date类对象

Date类提供了很多构造方法,程序员可以根据需要调用不同的构造方法创建Date类对象,下面的表10-1展示了Date类的各种构造方法。​

表10-1 Date类的构造方法​

构造方法​

作用​

Date()​

获取系统当前日期时间​

Date(int year, int month, int date)​

以int型参数指定日期​

Date(int year, int month, int date, int hrs, int min)​

以int型参数指定日期时间(精确到分钟)​

Date(int year, int month, int date, int hrs, int min, int sec)​

以int型参数指定日期时间(精确到秒钟)​

Date(String s)​

以字符串指定日期时间​

Date(long date)​

以long型参数指定日期时间​

有时程序员需要创建一个表示当前日期时间的Date类对象,例如:互联网购物平台在完成一次购物操作时,要在完成购物的同时记录购买时间,这种场景下购买时间就取自于服务器的当前系统时间。使用Date类的无参数构造方法所创建出的对象就是当前系统时间,例如:​

Date date = new Date();

有时程序员需要记录一个日期,例如某个同学出生于2001年2月5日,程序员可以通过以下语句所创建的Date类对象来表示这个日期:​

Date date = new Date(101,1,5);

在这行代码中,Date类构造方法的三个参数分别表示年、月、日。不难发现:出生年份是2001,但是代码中为构造方法设定的第一个参数值却是101,而出生月份是2月,但代码中为构造方法设定的第二个参数值却是1。这是因为Date类构造方法中,表示年份的参数比实际的年份小1900。以上语句中把表示年份的参数设定为101,这个101实际上代表的就是2001年。此外,Date类构造方法中表示月份的参数比实际的月份小1,因此代码把表示月份的参数设定为1实际上表示的是2月。​

如果希望在程序中不仅仅表示出某个日期,还能表示出这个日期中的时间,可以用以下代码来实现:​

Date date1 = new Date(101,1,5,6,5);
Date date2 = new Date(101,1,5,6,5,10);

在这段代码中创建了两个Date类对象d1和d2,创建d1所用的构造方法总共有5个参数,它们分别代表年、月、日、时、分,而创建d2所用的构造方法总共有6个参数,其中前5个参数分别代表年、月、日、时、分,最后一个参数代表秒。需要说明:表示时的参数范围是0-23,也就是0点到23点,而表示分和秒的参数范围都是0-59,也就是0到59分或秒。​

实际上,通过字符串也能创建出Date类对象,代码如下:​

Date date = new Date("Jan 01 2022");

以上代码中创建的Date类对象表示2022年1月1日,其中“Jan”就是英文单词一月的缩写。这个Date类对象只能表示日期,如果还想表示出这个日期中的时间,可以用以下代码实现:​

Date date = new Date("Jan 01 2022 08:00:00");

在这段代码中,创建Date类对象时在字符串中加入了“08:00:00”,这部分内容就表示时间,具体来说它表示早上8点整。需要注意:字符串中所添加的时间默认表示计算机操作系统所设时区的时间,对于中国而言,它就是指北京时间。如果希望表示某个特定时区的时间,还可以在构造方法的字符串参数中加入时区的缩写,例如:​

Date date = new Date("Jan 01 2022 08:00:00 GMT");

这段代码中,构造方法的参数里添加了“GMT”,这个GMT就表示格林尼治时间,因此以上代码所创建的Date类对象表示的是格林尼治时间的2022年1月1日早上8点整。​

以上语句在创建出Date类对象时,构造方法的参数中都出现了月份的英文缩写,实际上很多程序员都不能准确的写出每个月的英文缩写。为此,Date类还提供了另一种设置日期时间的格式,这种格式是按照年月日时分秒的顺序来书写日期时间,例如:​

Date date = new Date("2022/01/01 08:00:00 GMT");

以上代码所创建出的Date对象表示格林尼治时间2022年1月1日早上八点整,如果去掉参数中的“GMT”,那么所创建的Date类对象表示北京时间2022年1月1日早上八点整。需要注意,构造方法的参数中出现了两个“01”,其中第一个“01”表示月,第二个“01”表示日。​

前文讲过:一个Date类对象实际上就表示一个时间点。那么这个时间点是怎样计算出来的呢?“时间原点”,这个时间原点是格林尼治时间的1970年1月1日0点0分0秒。Java语言的设计者在Date类中设置了一个long型的属性fastTime,fastTime的值就是一个时间点与时间原点相差的毫秒数。程序员在创建创建Date类对象时直接通过构造方法设置fastTime的值,例如:​

Date date = new Date(3600000);

以上代码设置fastTime的值为3600000,这表示所创建的date对象与时间原点相差3600000毫秒,3600000毫秒可以换算为1小时,因此以上代码中date对象所表示的时间是格林尼治时间1970年1月1日1点0分0秒。fastTime的值也可以是负数,正数表示晚于时间原点的毫秒数,而负数表示早于时间原点的毫秒数。以上介绍了各种创建Date类对象的方法,下面的【例10_01】展示了使用多种方式创建Date类对象的过程。​

【例10_01创建Date类对象】

Exam10_01.java​

import java.util.Date;
public class Exam10_01 {
public static void main(String[] args) {
//创建一个表示当前系统时间的Date对象
Date date1 = new Date();
//创建一个表示2001年2月5日的Date对象(北京时间)
Date date2 = new Date(101, 1, 5);
//创建一个表示2001年2月5日6点5分的Date对象(北京时间)
Date date3 = new Date(101, 1, 5, 6, 5);
//创建一个表示2001年2月5日6点5分10秒的Date对象(北京时间)
Date date4 = new Date(101, 1, 5, 6, 5, 10);
//创建一个表示2022年1月1日的Date对象(北京时间)
Date date5 = new Date("Jan 01 2022");
//创建一个表示2022年1月1日8点0分0秒的Date对象(北京时间)
Date date6 = new Date("Jan 01 2022 08:00:00");
//创建一个表示2022年1月1日8点0分0秒的Date对象(格林尼治时间)
Date date7 = new Date("Jan 01 2022 08:00:00 GMT");
//创建一个表示2022年1月1日8点0分0秒的Date对象(格林尼治时间)
Date date8 = new Date("2022/01/01 08:00:00 GMT");
//创建一个比时间原点晚3600000毫秒的Date对象
Date date9 = new Date(3600000);
}
}


10.1.2格式化输出Date类对象

使用println()方法打印Date类对象会在控制台上输出一个日期时间,这个日期时间是按照欧美国家习惯的格式显示的,请看下面的【例10_02】。​

【例10_02 直接输出Date类对象】

Exam10_02.java​

import java.util.Date;
public class Exam10_02 {
public static void main(String[] args){
Date date = new Date("2022/01/01 08:00:00 GMT");
System.out.println(date);
}
}

【例10_02】中创建了一个表示格林尼治时间2022年1月1日早上8点整的Date类对象。【例10_02】的运行结果如图10-1所示。​

第十章《日期与时间》第1节:Date类的使用

图10-1 【例10_02】运行结果​

图10-1中,Sat表示星期六,Jan表示一月,CST表示“China Standard Time”意为中国标准时间,也就是北京时间。可以看出:虽然date对象表示的是格林尼治时间,但把date对象输出到控制台上时却是按北京时间显示的。这是因为在Java语言中,无论一个Date类对象表示的是哪个时区的时间,只要把这个对象直接输出到控制台上,虚拟机都会按计算机操作系统所设置的时区来显示日期时间。因此date对象原本表示格林尼治时间2022年1月1日早上8点整,但却被输出为北京时间2022年1月1日下午16点整。​

通过图10-1还可以看出:直接输出Date类对象时,输出结果是以欧美国家的日期时间格式显示的。果程序员希望自定义Date类对象的显示格式,需要借助SimpleDateFormat类来对显示结果进行格式化。SimpleDateFormat这个类位于java.text包下,在程序中使用这个类时需要对其进行引入操作。SimpleDateFormat类中有一个format()方法,这个方法能够把Date类对象以指定的格式转换为字符串,下面的【例10_03】演示了如何使用SimpleDateFormat类完成Date类对象的格式化输出。​

【例10_03 格式化输出Date类对象】

Exam10_03.java​

import java.text.SimpleDateFormat;
import java.util.Date;
public class Exam10_03 {
public static void main(String[] args){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date("2022/01/01 08:00:00 GMT");
String str = sdf.format(date);//格式化Date类对象
System.out.println(str);

}
}

【例10_03】的代码中首先创建了一个SimpleDateFormat类对象sdf,在创建这个对象时为构造方法传递的字符串参数是“yyyy-MM-dd HH:mm:ss”这个字符串表示对日期时间设定的格式,格式中每个字母都有特定含义,而字母的个数则表示显示的数据占几位数。下面的表10-2列出了用于设置日期时间格式的各字母含义。​

表10-2 格式化字符串各字母含义​

字母

含义

y

M

月份

w

年中的周数

W

月份中的周数

D

年中的天数

d

月份中的天数

F

月份中的星期

E

星期

a

am/pm 标记

H

一天中的小时数(0-23)

h

am/pm 中的小时数(1-12)

K

am/pm 中的小时数(0-11)

k

一天中的小时数(1-24)

m

小时中的分钟数(0-59)

s

分钟中的秒数

S

毫秒数

【例10_03】中,年份的格式被设置yyyy,这表示年份值要按4位数显示,月份的格式被设置为MM,表示月份要按2位数显示。设置好日期时间的显示格式后,调用其format()方法可以对Date类对象进行格式化,格式化的结果是一个字符串,程序员只要把这个字符串输出到控制台上即可。【例10_03】的运行结果如图10-2所示。​

第十章《日期与时间》第1节:Date类的使用

图10-2【例10_03】运行结果​

从图10-2可以看出:date对象完全按照程序员设定的格式进行显示。需要注意:虽然date对象被设置为格林尼治时间,但它仍然按照操作系统设定的时区被显示为一个北京时间。在实际开发过程中,读者可以根据表10-2所列字母的含义灵活的设定日期时间的输出格式及显示内容。​

10.1.3 Date类获得时间分量

一个Date类对象表示一个日期时间,这个日期时间中的年、月、日、时、分、秒的数值都叫做“时间分量”。下面的表10-3列出了获取各时间分量的方法。​

方法

作用

int getYear()

获得年份

int getMonth()

获得月份

int getDate()

获得日期

int getDay()

获得星期

int getHours()

获得小时

int getMinutes()

获得分钟

int getSeconds()

获得秒钟

下面的【例10_04】展示了如何获得Date类对象中的时间分量。​

【例10_04 获得时间分量】

Exam10_04.java​

import java.util.Date;
public class Exam10_04 {
public static void main(String[] args){
Date date = new Date("2022/01/01 16:45:55");
System.out.println("年:"+date.getYear());
System.out.println("月:"+date.getMonth());
System.out.println("日:"+date.getDate());
System.out.println("星期:"+date.getDay());
System.out.println("时:"+date.getHours());
System.out.println("分:"+date.getMinutes());
System.out.println("秒:"+date.getSeconds());
}
}

【例10_04】的运行结果如图10-3所示。​

第十章《日期与时间》第1节:Date类的使用

图10-3【例10_04】运行结果​

从图10-3可以看出,使用Date类获得时间分量的方法对于年和月这两项数据的计算与真实日期时间有一定的偏差,date对象所表示的年份是2022年,而实际获得的数值是122,月份是1月,而实际获得的数值是0,因此各位读者在使用这些方法获得时间分量时一定要对年和月这两个时间分量加以修正。

本文字版教程还配有更详细的视频讲解,小伙伴们可以点击这里观看。