首页 > 编程笔记 > Java笔记 阅读:35

Java日期时间类详解(Date、DateFormat和Calendar)

在程序开发中,经常需要处理日期时间,Java 中提供了专门的日期时间类来处理相应的问题,本节将对 Java 中的日期时间类进行详细讲解。

Java Date类

Date 类用于表示日期时间,使用该类表示时间需要使用其构造方法创建对象,其构造方法及其说明如下表所示。

表:Date 类的构造方法及其说明
构造方法 说明
Date() 分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)
Date(long date) 分配 Date 对象并初始化此对象,以表示自标准基准时间(即 1970 年 1 月 1 日 00:00:00 GMT)起经过指定毫秒数 date 后的时间

例如,使用 Date 类的第 2 种构造方法创建一个 Date 类的对象,代码如下:
long timeMillis = System.currentTimeMillis();  //当前系统时间所经历的毫秒数
Date date = new Date(timeMillis);
上述代码中的 System 类的 currentTimeMillis() 方法主要用来获取当前系统时间距标准基准时间的毫秒数。需要注意的是,创建 Date 对象时使用的是 long 型整数,而不是 double 型,这主要是因为 double 类型可能会损失精度。

Date 类的常用方法及其说明如下表所示:

表:Date 类的常用方法及其说明
方法 说明
after(Date when) 测试当前日期是否在指定的日期之后
before(Date when) 测试当前日期是否在指定的日期之前
getTime() 获得自 1970 年 1 月 1 日 00:00:00 GMT 开始到现在所经过的毫秒数
setTime(long time) 设置当前 Date 对象所表示的日期时间值,该值用以表示 1970 年 1 月 1 日 00:00:00 GMT 后 time 毫秒的时间点

【实例】获取当前的日期和时间,创建 Date 对象获取当前日期和时间并输出。
import java.util.Date;
public class DateDemo {
    public static void main(String[] args) {
       Date date = new Date();  //创建现在的日期
       long value = date.getTime();  //获得毫秒数
       System.out.println("日期:" + date);
       System.out.println("到现在所经历的毫秒数为:" + value);
   }
}
运行此代码后,将在控制台中输出日期及自 1970 年 1 月 1 日 00:00:00 GMT 开始至本程序运行时所经历过的毫秒数,结果如下:

标准输出:日期:Wed Apr 23 05:23:07 UTC 2025
到现在所经历的毫秒数为:1745385787942

因为代码执行的时间不同,所以每次“获取的当前时间”得到的结果都不会一样。

注意,本节介绍的 Date 类在 java.util 包下,但 java.sql 包下也有一个 Date 类,不要将二者搞混。

Java DateFormat类

如果在程序中直接输出 Date 对象,显示的是“Mon Feb 29 17:39:50 CST 2016”这种格式的日期时间,那么应该如何将其显示为“2016-02-29”或者“17:39:50”这样的日期时间格式呢?Java 中提供了 DateFormat 类来实现类似的功能。

DateFormat 类是日期时间格式化子类的抽象类,可以按照指定的格式对日期或时间进行格式化。

DateFormat 类提供了很多类方法,以获得基于默认或给定语言环境和多种格式化风格的默认日期时间 Formatter,格式化风格主要包括 SHORT、MEDIUM、LONG 和 FULL 4种:
另外,使用 DateFormat 类还可以自定义日期时间的格式。要格式化一个当前语言环境下的日期,首先需要创建 DateFormat 类的一个对象,由于它是抽象类,因此可以使用其静态方法 getDateInstance() 进行创建,语法如下:
DateFormat df = DateFormat.getDateInstance();
使用 getDateInstance() 方法获取的是所在国家或地区的标准日期格式。

DateFormat 类还提供了一些其他静态方法。例如,使用 getTimeInstance() 方法可获取所在国家或地区的时间格式,使用 getDateTimeInstance() 方法可获取日期和时间格式。

DateFormat 类的常用方法及其说明如下表所示:

表:DateFormat类的常用方法及其说明
方法 说明
format(Date date) 将一个 Date 对象实例格式化为日期/时间字符串
getCalendar() 获取与此日期/时间格式器关联的日历
getDateInstance() 获取日期格式器,该格式器具有默认语言环境的默认格式化风格
getDateTimeInstance() 获取日期/时间格式器,该格式器具有默认语言环境的默认格式化风格
getInstance() 获取为日期和时间使用 SHORT 风格的默认日期/时间格式器
getTimeInstance() 获取时间格式器,该格式器具有默认语言环境的默认格式化风格
parse(String source) 将字符串解析成一个日期,并返回这个日期的 Date 对象

例如,将当前日期按照 DateFormat 类默认格式进行输出:
DateFormat df = DateFormat.getInstance();
System.out.println(df.format(new Date()));
结果如下:

2025/1/18 17:03


输出长类型格式的当前时间:
DateFormat df = DateFormat.getTimeInstance(DateFormat.LONG);
System.out.println(df.format(new Date()));
结果如下:

CST 17:04:56


输出长类型格式的当前日期:
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
System.out.println(df.format(new Date()));
结果如下:

2025年1月18日


输出长类型格式的当前日期和时间:
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, DateFormat.LONG);
System.out.println(df.format(new Date()));
结果如下:

2025年1月18日 CST 17:06:44

由于 DateFormat 类是一个抽象类,不能用 new 创建实例对象。因此,除了使用 getXXXInstance() 方法创建其对象,还可以使用其子类,如 SimpleDateFormat 类,该类是一个以与语言环境相关的方式来格式化和分析日期的具体类,它允许进行格式化(日期→文本)、分析(文本→日期)和规范化。

SimpleDateFormat 类提供了 19 个格式化字符,可以让开发者随意编写日期格式,这 19 个格式化字符如下表所示。

表: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
h am/pm 中的小时数(1~12) Number 12
k 一天中的小时数(1~24) Number 24
K am/pm 中的小时数(0~11) Number 0
m 小时中的分钟数 Number 30
s 分钟中的秒数 Number 555
S 毫秒数 Number 978
z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
Z 时区 RFC 822 time zone -800

通常上表中的字符出现的数量会影响数字的格式。例如:yyyy 表示 4 位年份,这样输入会显示 2025;yy 表示两位,这样输入就会显示为 23;只有一个 y 的话,会按照 yyyy 显示;如果超过 4 个 y,如 yyyyyy,会在 4 位年份左侧补 0,结果为 02025。

一些常用的日期时间格式如下表所示:

表:常用日期时间格式
日期时间 对应的格式
2025/1/18 yyyy/MM/dd
2025.1.18 yyyy.MM.dd
2025-1-18 17:06:444 yyyy-MM-dd HH:mm:ss
2025 年 1 月 18 日 17 时 06 分 44 秒 星期三 yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒 EEE
下午 5 时 ah 时
今年已经过去了17 天 今年已经过去了 D 天

【实例】以中文形式输出当前的日期和时间。创建 DateFormatDemo 类,在主方法中创建日期格式化对象,将格式设定为“某年某月某日星期几某时某分某秒”,以新闻开头的方法播报当前时间。
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatDemo {
    public static void main(String[] args) {
        DateFormat df = new SimpleDateFormat("yyyy年MM月dd日EEEE HH时mm分ss秒");
        System.out.println("各位观众大家好,现在是");
        System.out.println(df.format(new Date()));
        System.out.println(",欢迎收看新闻。");
    }
}
运行结果如下:

各位观众大家好,现在是2025年01月18日 星期三 17时14分59秒,欢迎收看新闻。


DateFormat 类提供的 Date parse(String source) 方法可以将字符串转为其字面日期对应的 Date 对象,整个过程相当于日期格式化的逆操作。

例如,将“2025-1-18”字符串转成 Date 对象,可以使用如下代码:
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2025-1-18");
如果日期字符串不符合格式,则会抛出 java.text.ParseException 异常。

Java Calendar类

打开 Java API 文档可以看到 java.util.Date 类提供的大部分方法都已经过时了,因为 Date 类在设计之初没有考虑到国际化,而且很多方法也不能满足用户需求,比如需要获取指定时间的年月日时分秒信息,或者想要对日期时间进行加减运算等复杂的操作,Date 类已经不能胜任,因此 JDK 提供了新的时间处理类—Calendar 日历类。

Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOU R等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期)提供了一些方法。

另外,Calendar 类还为实现包范围外的具体日历系统提供了其他字段和方法,这些字段和方法被定义为 protected。

Calendar 提供了一个类方法 getInstance(),以获得此类型的一个通用的对象。Calendar 类的 getInstance() 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化,其使用方法如下:
Calendar rightNow = Calendar.getInstance();
由于 Calendar 类是一个抽象类,不能用 new 创建实例对象,因此只能使用 getInstance() 方法创建该类的实例对象。如果需要创建 Calendar 类的对象,必须使用其子类,如 GregorianCalendar 类。

Calendar 类提供的常用字段及其说明如下表所示:

表:Calendar类提供的常用字段及其说明
字段名 说明
DATE get 和 set 的字段数字,指示一个月中的某天
DAY_OF_MONTH get 和 set 的字段数字,指示一个月中的某天
DAY_OF_WEEK get 和 set 的字段数字,指示一个星期中的某天
DAY_OF_WEEK_IN_MONTH get 和 set 的字段数字,指示当前月中的第几个星期
DAY_OF_YEAR get 和 set 的字段数字,指示当前年中的天数
HOUR get 和 set 的字段数字,指示上午或下午的小时
HOUR_OF_DAY get 和 set 的字段数字,指示一天中的小时
MILLISECOND get 和 set 的字段数字,指示一秒中的毫秒
MINUTE get 和 set 的字段数字,指示一小时中的分钟
MONTH 指示月份的 get 和 set 的字段数字
SECOND get 和 set 的字段数字,指示一分钟中的秒
time 日历的当前设置时间,以毫秒为单位,表示自格林威治标准时间 1970 年 1 月 1 日 0:00:00 后经过的时间
WEEK_OF_MONTH get 和 set 的字段数字,指示当前月中的星期数
WEEK_OF_YEAR get 和 set 的字段数字,指示当前年中的星期数
YEAR 指示年的 get 和 set 的字段数字

Calendar 类提供的常用方法及其说明如下表所示:

表:Calendar类提供的常用方法及其说明
方法 说明
add(int field, int amount) 根据日历的规则,为给定的日历字段添加或减去指定的时间量
after(Object when) 判断此 Calendar 对象表示的时间是否在指定 Object 表示的时间之后,返回判断结果
before(Object when) 判断此 Calendar 对象表示的时间是否在指定 Object 表示的时间之前,返回判断结果
get(int field) 返回给定日历字段的值
getInstance() 使用默认时区和语言环境获得一个日历
getTime() 返回一个表示此 Calendar 对象时间值(从历元至现在的毫秒偏移量)的 Date 对象
getTimeInMillis() 返回此 Calendar 对象的时间值,以毫秒为单位
roll(int field, boolean up) 在给定的时间字段上添加或减去(上/下)单个时间单元,不更改更大的字段
set(int field, int value) 将给定的日历字段设置为给定值
set(int year, int month, int date) 设置日历字段 YEAR、MONTH 和 DAY_OF_MONTH 的值
set(int year, int month, int date, int hourOfDay, int minute) 设置日历字段 YEAR、MONTH、DAY_OF_MONTH、HOUR_OF_DAY 和 MINUTE 的值
set(int year, int month, int date, int hourOfDay, int minute, int second) 设置字段 YEAR、MONTH、DAY_OF_MONTH、HOUR_OF_DAY、MINUTE 和 SECOND 的值
setTime(Date date) 使用给定的 Date 对象设置此 Calendar 对象的时间
setTimeInMillis(long millis) 用给定的 long 值设置此 Calendar 对象的当前时间值

从表中可以看到,add() 方法和 roll() 方法都用来为给定的日历字段添加或减去指定的时间量,它们的主要区别在于:
【实例】今天离中华人民共和国成立 100 周年差多少天。创建 CountDown 类,通过 Calendar 类和 Date 类计算出 2049 年 10 月 1 日距今相差的毫秒数,根据毫秒数计算出相差的天数。
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CountDown {
    public static void main(String[] args) {
        System.out.println("——中华人民共和国成立100周年倒计时——");
        Date date = new Date(); // 当前时间
        // 创建 SimpleDateFormat 对象,指定目标格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy 年 MM 月 dd 日");
        // 调用 format 方法,格式化时间,转换为指定格式
        String today = simpleDateFormat.format(date);
        System.out.println("今天是" + today); // 输出当前日期

        // 获取自 1970 年 1 月 1 日至当前时间所经过的毫秒数
        long time1 = date.getTime();
        // 使用默认时区和语言环境获得一个日历 calendar
        Calendar calendar = Calendar.getInstance();
        // 设置日历 calendar 的年、月和日的值。因为月份是从 0 开始计算的,所以这里要减 1
        calendar.set(2049, 10 - 1, 1);
        // 计算自 1970 年 1 月 1 日至 2049 年 10 月 1 日所经过的毫秒数
        long time2 = calendar.getTimeInMillis();
        // 计算 2049 年 10 月 1 日距离当前时间相差的天数
        long day = (time2 - time1) / (1000 * 60 * 60 * 24);
        System.out.println("距离2049年10月1日还有" + day + "天!");
    }
}
——中华人民共和国成立100周年倒计时——

今天是 2025 年 04 月 23 日
距离 2049 年 10 月 1 日还有 8927 天!


最后对 Calendar 类的使用做出几点总结:

相关文章