Java 学习之路 之 处理日期的类 (二十九)

Java 还提供了一系列用于处理日期、时间的类,包括创建日期、时间对象,获取系统当前日期、时间等操作。

1,Date 类

Java 提供了 Date 类来处理日期、时间(此处的 Date 是指 java.util 包下的 Date 类,而不是 java.sql 包下的 Date 类),Date对象既包含日期,也包含时间。Date 类从 JDK 1.0 起就开始存在了。但正因为它历史悠久,所以它的大部分构造器、方法都已经过时,不再推荐使用了。

Date 类还提供了 6 个构造器,其中 4 个已经 Deprecated(Java 不再推荐使用,使用不再推荐的构造器时编译器会提出警告信息,并导致程序性能、安全性等方面的问题),剩下的两个构造器如下所示。

Date():生成一个代表当前日期时间的 Date 对象。该构造器在底层调用 System.currentTimeMillis() 获得 long 整数作为日期参数。

Date(long date):根据指定的 long 型整数来生成一个 Date 对象。该构造器的参数表示创建的 Date 对象和 GMT 1970 年 1 月 1 日 00:00:00 之间的时间差,以毫秒作为计时单位。

boolean after(Date when):测试该日期是否在指定日期 when 之后。

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

int compareTo(Date anotherDate):比较两个日期的大小,后面的时间大于前面的时间时返回-1,否则返回 1。

boolean equals(Object obj):当两个时间表示同一时刻时返回 true。

long getTime():返回该时间对应的 long 型整数,即从 GMT 1970-01-01 00:00:00 到该 Date 对象之间的时间差,以毫秒作为计时单位。

void setTime(long time):设置该 Date 对象的时间。

package com.demo;

import java.util.Date;

public class DateTest {
	public static void main(String[] args) {
		Date d1 = new Date();
		//获取当前时间之后 100ms 的时间
		Date d2 = new Date(System.currentTimeMillis() + 100);
		System.out.println(d2);
		System.out.println(d1.compareTo(d2));
		System.out.println(d1.before(d2));
	}
}
因为 Date 类的很多方法已经不推荐使用了,所以 Date 类的功能已经被大大削弱了。例如,对时间进行加减运算,获取指定 Date 对象里年、月、日的所有方法都已 Deprecated, 如果需要对日期进行这些运算,则应该使用 Calendar 工具类。

2,Calendar 类

因为 Date 类在设计上存在一些缺陷,所以 Java 提供了 Calendar 类来更好地处理日期和时间。Calendar 是一个抽象类,它用于表示日历。

Calendar 类是一个抽象类,所以不能使用构造器来创建 Calendar 对象。但它提供了几个静态 getInstance() 方法来获取 Calendar 对象,这些方法根据 TimeZone,Local 类来获取特定的 Calendar,如果不指定 TimeZone、Local,则使用默认的 TimeZone、Local 来创建 Calendar。

Calendar 与 Date 都是表示日期的工具类,它们直接可以自由转换。

//创建一个默认的 Calendar 对象
Calendar calendar = Calendar.getInstance();
//从 Calendar 对象中取出 Date 对象
Date date = calendar.getTime();
//通过 Date 对象获取得对应的 Calendar 对象
//因为 Calendar/GregorianCalendar 没有构造器函数可以接受 Date 对象
//所以必须先获得一个 Calendar 实例,然后调用其 setTime() 方法
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date);
Calendar 类提供了大量访问、修改日期时间的方法,常用方法如下。

void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。

int get(int field):返回指定日历字段的值。

int getActualMaximun(int field):返回指定日历字段可能拥有的最大值。

int getActualMinimun(int field):返回指定日历字段可能拥有的最小值。

void roll(int field, int amount):与 add() 方法类似,区别在于加上 amount 后超过了该字段所能表示的最大范围时,也不会向一个字段进位。

void set(int field, int value):将给定的日历字段设置为给定值。

void set(int year, int month, int date):设置 Calendar 对象的年、月、日 3 个字段的值。

void set(int year, int month, int date, int hourOfDay, int minute, int second):设置 Calendar 对象的年、月、日、时、分、秒 6 个字段的值。

上面的很多方法都需呀一个 int 类型的 field 参数, field 是Calendar 类的静态 Field,如 Calendar.YEAR、Calendar.MONTH 等分别代表了年、月、日、小时、分钟、秒等时间字段。需要指出的是,Calendar.MONTH字段代表月份,月份的起始值不是1,而是0。

a,add 与 roll 的区别

add(int field, int amount)的功能非常强大,add 主要用于改变 Calendar 的特定字段的值。如果需要增加某字段的值,则让 amount 为正数;如果需要减少某字段的值,则让 amount 为负数即可。

add(int field, int amount)有如下两条规则。

当被修改的字段超出它运行的范围时,会发生进位,即上一级字段也会增大。

如果下一几字段也需要改变,那么该字段会修正到变化最小的值。

roll的规格与 add 的处理规则不同:当被修改的字段超出它允许的范围时,上一级字段不会增大。

下一级字段的处理规则与 add 相似:

b,设置 Calendar 的容错性

当我们调用 Calendar 对象的 set 方法来改变指定时间字段上的值时,有可能传入一个不合法的参数,例如为 MONTH 字段设置 13,这将会导致怎样的结果呢?看如下程序。

package com.demo;

import java.util.Calendar;

public class LenientTest {
	public static void main(String[] args) {
		Calendar cal = Calendar.getInstance();
		//结果是 YEAE 字段加 1,MONTH 字段为 1(2月)
		cal.set(MONTH, 13);    //①
		System.out.println(cal.getTime());
		//关闭容错性
		cal.setLenient(false);
		//导致运行时异常
		cal.set(MONTH, 13);    //②
		System.out.println(cal.getTime());
	}
}
上面程序1,2两处的代码完全相似,但它们运行的结果不一样:1处代码可以正常运行,因为设置 MONTH 字段的值为 13,将会导致 YEAR字段加 1;2出代码将会导致运行时异常,因为设置的 MONTH 字段值超出了 MONTH 字段运行的范围。关键在于程序中粗体字代码行,Calendar 提供了一个 setLenient() 用于设置它的容错性,Calendar 默认支持较好的容错性,通过 setLenient(false) 可以关闭 Calendar 的容错性,让它进行严格的参数检查。

c,set 方法延迟修改

set(f, value) 方法将日历字段 f 更改为 -- value,此外,它还设置了一个内部成员变量,以知识日历字段 f 已经被更改,但该 Calendar 所代表的的时间却不会立即修改,直到下次调用 get()、getTime()、getTimeMillis()、add() 或 roll() 时才会重新计算日历的时间。这被称为 set 方法的延迟修改,此阿勇延迟修改的优势是多次调用 set() 不会触发多次不必要的计算(需要计算出一下代表实际时间的 long 型整数)。

3,TimeZone 类

在地理上,地球被划分成 24 个时区,中国北京时间属于东八区,而程序中对时间的默认实现是以格林威治时间为标准的,这样就产生了 8 小时的时间差。为了让程序更加通用,可以使用TimeZone 设置程序中时间所属的时区,其中 TimeZone 就代表了时区。

TimeZone 是一个抽象类,不能调用其构造器来创建实例,但可以通过它的静态方法:getDefault()或 getTimeZone() 得到 TimeZone 实例。其中 getDefault() 方法用于获得运行机器上的默认时区,默认时区可以通过修改操作系统的相关配置来进行调整:getTimeZone() 则根据时区 ID 来获取对应的时区。

对于 Windows 系统而言,用户打开“控制面板”,单击控制面板里的“日期和时间” 按钮,即可打开设置时区对话框。

TimeZone 类提供了一些有用的方法用于获取时区的相关信息。

static String[] getAvailableIDs():获取Java 所支持的所有时区 ID。

static TimeZone getDefault():后去运行机器上默认的时区。

String getDisplayName():获取该 TimeZone 对象的时区名称。

String getID():获取该时区的 ID。

static TimeZone getTimeZone(String ID):获取指定 ID 对应的 TimeZone 对象。

下面看一个使用 TimeZone 类的例子程序。

package com.demo;

import java.util.Arrays;
import java.util.TimeZone;

public class TimeZoneTest {
	public static void main(String[] args) {
		//获取 Java 所支持的所有时区 ID
		String[] ids = TimeZone.getAvailableIDs();
		System.out.println(Arrays.toString(ids));
		TimeZone my = TimeZone.getDefault();
		//获取系统默认时区的 ID:Asia/Shanghai
		System.out.println(my.getID());
		//获取系统默认时区的名称:中国标准时间
		System.out.println(my.getDisplayName());
		//获取指定 ID 的时区名称:纽芬兰标准时间
		System.out.println(TimeZone.getTimeZone("CNT").getDisplayName());
	}
}
上面程序中粗体字代码示范了 TimeZone 类的基本用法,程序运行后可以看到 Java 所支持的所有时区 ID:如果需要取得指定时区,则可以通过 getTimeZone() 方法取得指定 ID 对应的时区。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值