欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

90.Java日期处理

程序员文章站 2022-04-28 21:04:21
...

1 Date类

 

 

 

在编写程序的时候,不可避免的要用到日期,要进行日期方面的处理。在Java中,提供了一个用于日期(包括时间)处理的类Date,这个类位于java.util包中。这个类在JDK1.0开始就存在了。下面我们来看一下如何使用java.util.Date类来处理日期。

虽然在Date中定义了6个构造器,但是,其中的四个已经变成了Deprecated了,也就是说,这四个构造器已经不被推荐使用了。剩下的两个构造器分别为:
Date():生成一个代表当前时间的日期对象
Date(long date):根据指定的参数生成一个日期对象,其中的long类型的参数表示从格林威治标准时间(Greenwich Mean Time,GMT)1970年1月1日 00:00:00秒以来的毫秒数。


和构造器的命运一样,在Date中的大部分方法,到现在已经被标为Deprecated了,这也可以看出JDK1.0设计上存在的诸多缺陷。

 

下面是一些常用的未被Deprecated的方法:
boolean after(Date when):测试该日期是否比参数中指定的的日期早
boolean before(Date when):测试该日期是否比参数中指定的日期迟
long getTime():得到从格林威治标准时间1970年1月1日 00:00:00到这个Date对象所表示的日期之间的相隔的时间,单位为毫秒
void setTime(long date):设置这个Date对象表示的时间,参数为从格林威治标准时间1970年1月1日 00:00:00到需要设置的日期之间的毫秒数


2 Calendar类

 

 

正是因为Date设计上的缺陷,所以在JDK1.1以后,基本上就不使用这个类来处理日期和时间了,取而代之的是一个更加成熟完善的类Calendar,它也位于java.util包中。
 

 

Calendar是一个抽象类,用来表示日历的概念。因为它是一个抽象类,所以我们不能使用它的构造器来直接实例化它。

 

但是,在这个类中,提供了很多的静态方法getInstance(),可以让我们轻松的获得Calendar类型的对象(准确的说,这个方法获得的是一个Calendar的子类GregorianCalendar的实例,GregorianCalendar表示的是我们通常所说的阳历),我们首先来看这些方法:
Calendar getInstance():获得一个默认时区、默认地点(Locale)的Calendar对象。
Calendar getInstance(Locale locale):获得一个默认时区,指定地点(Locale)的Calendar对象
Calendar getInstance(TimeZone tz):获得一个指定时区,默认地点(Locale)的Calendar对象
Calendar getInstance(TimeZone tz,Locale locale):获得一个指定时区,指定地点(Locale)的Calendar对象
当然,也可以使用GregorianCalendar的构造器来获得对应的GregorianCalendar实例。

下面我们来看一下Calendar的常用的方法:


int add(int field,int value):改变对应的field的值,注意在这里之所以是“改变”而不是“增加”,是因为除了增加外,还可以减少对应field的值,只要给它一个负值就可以了。另外也没有对应的minus()方法或者substract()方法进行减少的运算,这个方法有3点需要注意:
当被修改的field超出它所能接受的值的范围时,比它大的field将会自动修正成可接受的值,这有点类似于我们做算术运算时候的“进位”:当个位为9的时候,再加上大于等于1的值,将会往十位进1。但是和算术运算略有不同的是,不用的field发生进位的“进制”不同,如日期超过28(2月份)、29(闰2月)、30、31都可能,而分钟是60等等。例如,在表示2006-5-31的Calendar对象上调用add(Calendar.DAY_OF_MONTH,2),将会得到一个表示2006-6-2的值,而当在它上面调用add(Calendar.DAY_OF_MONTH,42)的时候,将会得到表示2006-7-11的值。

当field的值发生改变的时候,比它小的field的值也可能会发生改变,因为当field发生改变的时候,它的最大值和最小值均可能发生改变,此时,更小的field中的值会调整到尽可能和所期望的值靠近的一个值。例如,在表示2006-5-31日的Calendar对象上调用add(Calendar.MONTH,1),除了月份会变成6月份以外,因为6月没有31日,所以日期这个field也会自动调整到30日


Calendar上调用add()方法的时候,将会马上改变Calendar的毫秒数和所有field


void roll(int field,int value):和add()方法类似,区别在于,即使加上value后对应的field值已经超出了它所能表示的最大范围,也不会改变更大的field的值


int get(int field):根据指定的field,返回相应的时间值。通常,参数field使用Calendar的静态常量来表示,例如:想得到当前的月份,可以使用方法get(Calendar.MONTH)来获得


int getActualMaximum(int field):获得指定的时间字段(field)所能表示的最大值,例如,如果使用getActualMaximum(Calendar.MONTH),将会得到一个11的值,表示月份最大值为11,注意,在Calendar中,月份是从0开始计算的,也就是说,1月份对应的数值是0,12月份对应的数值是11


int getActualMinimum(int field):获得指定的时间字段(field)所能表示的最小值,例如,如果使用getActualMinimum(Calendar.DAY_OF_WEEK),将会得到一个1的值,表示星期的最小值为1


int getFirstDayOfWeek():获得表示星期的第一天的数值


java.util.Date getTime():获得一个这个Calendar所表示的日期的对应的Date类型的值


long getTimeInMillis():获得以毫秒表示的时间值


void set(int field,int value):给一个对应的字段field设置一个值,例如,将日期设置成25号,可以调用set(Calendar.DAY_OF_MONTH,25)


void set(int year,int month,int day):设置年、月、日,这里需要注意的是月份是从0开始的


void set(int year,int month,int day,int hour,int minute):设置年、月、日、时、分


void set(int year,int month,int day,int hour,int minute,int secondd):设置年、月、日、时、分、秒


void setTime(Date time):将Calendar对象的当前时间设置成Date表示的值


void setTimeInMillis(long time):设置Calendar对象的当前时间为指定time的值


提示:
 set()方法和add()/roll()方法有一个重要的不同点:set()方法除了将相关的field的值改成新的值外,它会设置一个内部成员变量,用于标示Calendar字段的改变,尽管Calendar字段f是立即更改的,但是它所代表的时间值却不会马上改变,而是会在下次调用get()/getTime()/getTimeInMillis()/add()/roll()时才会重新计算。


下面我们来看一些Calendar的例子。

import java.util.*;

public class TestCalendar {
 public static void main(String[] args) {
  Calendar cal1 = Calendar.getInstance();
  cal1.set(2006, 5, 30, 0, 0, 0); // 2006-6-30
  cal1.add(Calendar.DAY_OF_MONTH, 32);
  System.out.println("月份:" + cal1.get(Calendar.MONTH));
  System.out.println("日期:" + cal1.get(Calendar.DAY_OF_MONTH));
 }
}


这个程序将会打印出如下的信息:
月份:7
日期:1


3 TimeZone类

 

 

 

在地理上,地球被划分为24个时区,中国北京时间属于东八区,而程序中对于时间的默认实现是以格林威治时间为标准,这样就产生了八个小时的时差,所以为了让你的程序更加通用,我们必须明确说明该时间是哪个时区的时间。在Java中,有一个类TimeZone用于表示时区的概念。

 

 


TimeZone是一个抽象类,它表示的是一个时区的概念。我们可以使用这个抽象类上面的静态方法getDefault()来获得程序所运行机器上的默认时区,这个默认时区通常可以通过修改操作系统的相关配置来调整。


在TimeZone上还有一些有用的方法,我们可以通过它们来获得一些相关的信息:


String[] getAvailableIDs()/getAvailableIDs(int offset):获得所有有效的时区ID。时区ID是用于标示一个时区的值,例如,北京时间的ID其实是Asia/Shanghai。参数offset表示偏移格林威治时间的时差。
String getID():获得对应此TimeZone的ID。
String getDisplayName():获得对应时区的显示名称,例如,北京时间的显示名称为“中国标准时间”。


我们来看一个TimeZone的例子。

import java.util.*;

public class TestTimeZone {
 public static void main(String[] args) {
  TimeZone tz = TimeZone.getDefault();
  System.out.println("ID是:" + tz.getID());
  System.out.println("显示名称是:" + tz.getDisplayName());
 }
}


这个程序中,我们首先使用TimeZone的静态方法getDefault()获得表示当前操作系统得默认时区,然后使用getID()和getDisplayName()来分别获得这个时区的ID和显示名。


编译运行这个程序可以得到如下输出:
ID是:Asia/Shanghai
显示名称是:中国标准时间