Java 日期处理 Date 、Calendar 和TimeZone类

来源:互联网 发布:淘宝上新速度 编辑:程序博客网 时间:2024/04/30 18:01

以下内容部分来自 疯狂Java讲义/李刚 ,博客仅用于个人笔记及帮助他人用途,无任何商业目的,如有侵权,请联系作者删除。

Date 类

Java提供了 Date 类来处理日期、时间(此处的Date是指 java.util包下的Date类,而不是java.sql 包下的Date类),Date对象既包含日期,也包含时间。Date类从 JDK1.0 起就开始存在了。但正因为它历史悠久,所以它的大部分构造器、方法都己经过时,不再推荐使用了。
Date类提供了6个构造器,其中4个己经Deprecated(Java不再推荐使用,使用不再推荐的构造器时编译器会提出警告信息,并导致程序性能、安全性等方面的问题),剩下的两个构造器如下所示:

(1)Date():生成一个代表当前日期时间的 Date 对象。该构造器在底层调用System.currentTimeMillis0获得long整数作为日期参数。
(2)Date(long date):根据指定的 long 型整数来生成一个Date对象。该构造器的参数表示创建的Date对象和 GMT1970年1月1日00:00:00 之间的时间差,以毫秒作为计时单位。

与Date构造器相同的是,Date对象的大部分方法也Deprecated了,剩下为数不多的几个方法·
(1)boolean after(Date when):测试该日期是否在指定日期when之后。
(2)boolean before(Date when):测试该日期是否在指定日期when之前。
(3)int compareTo(Date anotherDate):比较两个日期的大小,后面的时间大于前面的时间时返回 -1,否则返回1。
(4)int (Obj obj):当两个时间表示同一时刻时返回。
(5)long getTime():返回该时间对应的 long 型整数,即从 GMT1970-01-01 00:00:00到该Date对象之间的时间差,以毫秒作为计时单位。
(6)void setTime(long time):设置该Date对象的时间。

Calendar 类

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

我们知道:历史上有着许多种纪年方法,它们的差异实在太大了,比如说一个人的生日是“七月七日”,那么一种可能是阳(公)历的七月七日,但也可以是阴(农)历的日期,为了统一计时,全世界通常选择最普及、最通用的日历:Gregorian Calendar,也就是我们在讲述年份时常用的“公元几几年”。

Calendar 类本身是一个抽象类,它是所有日历类的模板,并提供了一些所有日历通用的方法,但它本身不能直接实例化,程序只能创建 Calendar 子类的实例,Java本身提供了一个GregorianCalendar类,一个代表的子类,它代表了我们通常所说的公历。
当然,也可以创建自己的Calendar了类,然后将它作为Calendar对象使用(这就是多态)。在IBM的alphaWorks站点(http://wwv.alphaworks.ibm.com/tech/calendars)上,IBM的开发人员实现了多种日历。在Internet上,也有对中国农历的实现。
Calendar类是一个抽象类,所以不能使用构造器来创建Calendar对象。但它提供了几个静态 getInstance() 方法来获取Calendar对象,这些方法根据Timezone,Locale 类来获取特定的Calendar,如果不指定Timezone、Locale,则使用默认的TimeZone、Locale来创建Calendar。

Calendar类提供了大量访问、修改日期时间的方法,常用方法如下。
(1)void add(int field,int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。
(2)int get(int field):返回指定日历字段的值。
(3)int getActualMaximum(int field):返回指定日历字段可能拥有的最大值·例如月,最大值为11。
(4)int getActualMinimum(int Id):返回指定日历字段可能拥有的最小值·例如月,最小值为0。
(5)void roll(int amount):与d()方法类似,区别在于加上amount后超过了该字段所能表示的最大范围时,也不会向上一个字段进位。
(6)void set(int field,int value):将给定的日历字段设置为给定值。
(7)void set(int month,int date):设置 Calendar 对象的年、月、日3个字段的值。
(8)void set(int year,int month,int date,int hourOfDay,int minute,int second):设置Calendar对象的年、月、日、时、分、秒6个字段的值。

上面的很多方法都需要一个 int 类型的field参数,filed是Calendar类的静态Filed如Calendar.YEAR、Calendar.MONTH等分代表了年、月、日、小时、分钟、秒等时间字,需要指出的是,Calendar.MONTH字段代表月份,月份的起始值不是1,而是0,所以要设置8月时,用7而不是8。
如下程序示范了Calendar类的常规用法:

    package Seventh;    import java.util.*;    import java.util.Calendar.*;    public class CalendarTest{        public static void main(String[] args){          Calendar c = Calendar.getInstance();          System.out.println(c.get(Calendar.YEAR));          System.out.println(c.get(Calendar.MONTH));          System.out.println(c.get(Calendar.DATE));          c.set(2003,10,23,12,32,23);          System.out.println(c.getTime());          c.add(Calendar.YEAR,-1);          System.out.println(c.getTime());          c.add(Calendar.MONTH,-8);          System.out.println(c.getTime());        }}

Calendar类还有如下几个注意点:

1.add 与 roll 的区别
add(int field,int amount)的功能非常强大,add 主要用于改变Calendar的特定字段的值。如果需要增加某字段的值,则让amount为正数:如果需要减少某字段的值,则让amount为负数即可。
add(int filed,int amount)有如下两条规则。
(1) 当被修改的字段超出它允许的范围时,会发生进位,即上一级字段也会增大。如下:

        Calendar call = new Calendar.getInstance();        Call.set(2003, 7, 23, 0, 0, 0);   //2003-8-23        Call.add(MONTH , 6); // 2003-8-23  => 2004-2-23

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

        Calendar cal2 = new Calendar.getInstance();        Cal2.set(2003, 7, 31, 0, 0, 0);   //2003-8-31        //因为进位后月份改为 2 月, 2 月没有 31 日,自动变为 29 日        Cal2.add(MONTH , 6); // 2003-8-31  => 2004-2-29

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

2.设置 Calender 的容错性
Calend 提供了一个 setLenient() 用于设置它的容错性,Calendar默认支持较好的容错性,通过setLenient(false)可以关闭Calendar的容错性,让它进行严格的参数检查。
Calendar有两种解释日历字段的模式:lenient模式和non-lenient模式,当 Calendar 处于lenient 模式时,每个时间字段可接受超出它允许范围的值;当Calendar处于non-lenient模式时,如果为某个时 间字段设置的值超出了它允许的取值范围,程序将会抛出异常·

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

TimeZone类

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

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

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

Timezone类提供了一些有用的方法用于获取时区的相关信息·
(1)static String[] getAvailablelDs():获取Java所支持的所有时区ID。
(2)static Timezone getDefault():获取运行机器上默认的时区。
(3)String getDisplayName():获取该下TimeZone对象的时区名称。
(4)String getID():获取该时区的ID。
(5)static Timezone getTimeZone(String ID):获取指定ID对应的Timezone对象。
如下程序:

    package Seventh;    import java.util.*;    public class TimeZoneTest{        public static void main(String[] args){          String[] ids = TimeZone.getAvailableIDs();          System.out.println(Arrays.toString(ids));          TimeZone my = TimeZone.getDefault();          System.out.println(my.getID());          System.out.println(my.getDisplayName());    System.out.println(TimeZone.getTimeZone("CNT").getDisplayName());        }    }
0 0
原创粉丝点击