根据个人目前正在编写的《Java核心编程-基础篇》的规划,这部分属于第15章内容,这里沿用了书中的章节编号。另外,因为原文篇幅太长,这里适当做了删减。
15.1、概述
在 Java 8 之前,Java 语言表示时间的方法很简单,几乎都是采用毫秒值来表示时间。
比如获得系统当前时间可以使用以下方法:
long now = System.currentTimeMillis();
System.out.println( now );
这里获取的毫秒值是从 格里高利历 的 1970年1月1日 0点0分0秒0毫秒 至现在所经历的毫秒数。
即使是在 java.util.Date 类的实例 或 java.util.Calendar类的实例中,也仍然是通过毫秒值来表示时间。
因为 java.util.Date 类的实例 或 java.util.Calendar类在设计上的缺陷,
从 Java 8 开始提供了一个全新的包 (java.time ) 来表示时区、日期、时间。
接下来我们将从 Date 和 Calendar 说起,来研究 时期、时间的表示方法 以及 日期格式化 等操作。
15.2、Date 类
Date 类的实例表示特定的瞬间( 精确到毫秒 )。
package java.util;
import java.io.Serializable ;
public class Date implements Serializable, Cloneable, Comparable {
}
Date 类实现了 Serializable 、Cloneable 、Comparable 等接口。
15.2.1、实例字段
Date 类中封装了一个 long 类型的字段,用来保存 Date 实例所表示的时间:
private transient long fastTime;
15.2.2、构造方法
目前还有两个未被废弃的构造方法:
public Date( long millis ) {
fastTime = millis ;
}
public Date() {
this( System.currentTimeMillis() );
}
举例:
import java.util.Date;
public class DateTest1 {
public static void main(String[] args) {
// 构造方法内部将 System.currentTimeMillis() 保存到 fastTime 字段中
Date date = new Date();
System.out.println( date ); // CST : China Standard Time
// 构造方法内部将 -1000L 保存到 fastTime 字段中
Date d = new Date( -1000L );
System.out.println( d );
}
}
注意,输出 date 对象的字符串形式时,CST 表示 China Standard Time ,即中国标准时间。
15.2.3、实例方法
Date 类中绝大多数实例方法都已经被废弃(不赞成使用),仅存的几个可用的实例方法如下:
public long getTime()
获取 Date 实例内部存储的毫秒值。
public void setTime( long time )
设置 Date 实例内部存储的毫秒值。
public String toString()
将当前 Date 实例所存储的毫秒值转换为以下形式的 字符串:
dow mon dd hh:mm:ss zzz yyyy
其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
public boolean equals( Object obj )
Date 类重写了从 Object 类继承的 equals 方法用于判断当前 Date 实例与另外一个对象是否"相等"。
public boolean after( Date when )
测试 当前 Date 实例 所表示的时间 是否在 指定Date实例 所表示的时间之后。
public boolean before( Date when )
测试 当前 Date 实例 所表示的时间 是否在 指定Date实例 所表示的时间之前。
15.2.3.1、Date实例是可变的
Date 实例 是 【可变的】,在创建 Date 实例后,其内部的 毫秒值 是可以更改的
import java.util.Date;
public class DateTest2 {
public static void main(String[] args) {
long ms = 1000L * 60 * 60 * 24 * 365 * 30 ;
final Date date = new Date( ms );
System.out.println( date );
birthdate.setTime( 1000 );
System.out.println( date );
}
}
15.2.3.2、比较Date实例
Date实例的比较,可以通过 equals 、after 、before 方法来实现:
import java.util.Date;
public class DateTest3 {
public static void main(String[] args) {
long ms = 1000L * 60 * 60 * 24 * 365 * 30 ;
Date first = new Date( ms );
System.out.println( first );
Date second = new Date( ms );
System.out.println( second );
System.out.println( first == second ); // false
// java.utl.Date 类 重写了 从 Object 类继承的 equals 方法
System.out.println( first.equals( second ) ); // true
Date now = new Date();
System.out.println( now.after( first ) ); // true
System.out.println( now.after( second ) ); // true
System.out.println( first.before( now ) ); // true
System.out.println( second.before( now ) ); // true
}
}
不建议使用的比较方法是这样子的:
long firstTime = first.getTime() ;
long secondTime = second.getTime() ;
if( firstTime > secondTime ) {
System.out.println( first + " 晚于 " + second );
}
15.3 Calendar类
Calendar一词表示日历,而 Java 语言中 Calendar 则是一个类,一个声明在 java.util 包中的抽象类。
Calendar 类为特定瞬间与日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法
瞬间可用毫秒值来表示,它是距历元的偏移量。
历元(epoch) 是指 格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000 ( 格里高利历 ) 。
15.3.1、日历字段
日历字段是 Calendar 类中声明的用来表示日期时间中指定部分的常量。
常用的日历字段如下:
Calendar.ERA 对应纪元
比如罗马儒略历中的 AD 或 BC ( 中文表示为 公元 或 公元前 )
Calendar.YEAR 对应年份
Calendar.MONTH 对应月份
月份从 0 开始计数,0 表示 January (一月),1 表示 February ( 二月 )
Calendar.DATE 对应月份中的日期
日期从 1 开始计数,有效范围为 1 ~ 31 。
Calendar.HOUR_OF_DAY 对应一天当中的小时
小时从 0 开始计数,有效范围为 0 ~ 23 。
Calendar.MINUTE 对应分钟
分钟从 0 开始计数,有效范围为 0 ~ 59 。
Calendar.SECOND 对应秒
秒数从 0 开始计数,有效范围为 0 ~ 60 。(要注意闰秒)
Calendar.MILLISECOND 对应毫秒
毫秒数从 0 开始计数,有效范围为 0 ~ 999 。
Calendar.DAY_OF_MONTH 对应月份中的日期
日期从 1 开始计数,有效范围为 1 ~ 31 。
Calendar.HOUR 对应上午或下午的小时
小时从 0 开始计数,有效范围为 0 ~ 11 。
Calendar.DAY_OF_WEEK 对应星期
用于指示一个星期中的某天。
该字段可取的值可以是 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY 和 SATURDAY。
Calendar.DAY_OF_YEAR 对应年份中的天数
指示当前年中的天数。一年中第一天的值为 1,最大值为 366 。
15.3.2、获取Calendar实例
15.3.2.1、通过创建子类实例的方式
GregorianCalendar 类是 Calendar 类的子类,
通过创建 GregorianCalendar类的实例即可使用 Calendar 中的方法。
Calendar c = new GregorianCalendar(); // 父类引用 指向 子类对象
System.out.println( c );
15.3.2.2、通过类方法获取
Calendar 类中定义了大量的类方法用于获取 Calendar 实例:
public static Calendar getInstance()
举例:
Calendar c = Calendar.getInstance();
System.out.println( c );
public static Calendar getInstance( TimeZone zone, Locale locale )
举例:
TimeZone zone = TimeZone.getDefault();
Locale locale = Locale.getDefault() ;
Calendar c = Calendar.getInstance( zone , locale );
System.out.println( c );
15.3.3、从 Calendar 实例中获取时间
Calendar 类中声明了以下方法用于从 特定瞬间 中获取 指定日历字段 对应的值:
public int get( int calendarField )
同时在 Calendar 类中声明了以下方法用于获取 Calendar实例所表示的瞬间对应的毫秒值:
public long getTimeInMillis()
举例:
import java.util.Calendar;
import java.util.GregorianCalendar;
public class CalendarTest1 {