4.2.2 Java类库中的GregorianCalendar类
在前面的例子中,已经使用了Java标准类库中的Date类。Date类的实例有一个状态,即特定的时间点。
尽管在使用Date类时不必知道这一点,但时间是用距离一个固定时间点的毫秒数(可正可负)表示的,这个点就是所谓的纪元(epoch),它是UTC时间1970年1月1日00:00:00。UTC是Coordinated Universal Time的缩写,与大家熟悉的GMT(即Greenwich Mean Time/格林威治时间)一样,是一种具有实践意义的科学标准时间。
但是,Date类所提供的日期处理并没有太大的用途。Java类库的设计者认为:像“December 31,1999,23:59:59”这样的日期表示法只是阳历的固有习惯。这种特定的描述法遵循了世界上大多数地区使用的Gregorian阳历表示法。但是,同一时间点采用中国的农历表示和采用希伯来的阴历表示就很不一样,对于火星历来说就更不可想象了。
注释:有史以来,人类的文明与历法的设计紧紧地相连,日历给日期命名、给太阳和月亮的周期排列次序。有关世界上各种日历的有趣解释,从法国革命的日历到玛雅人计算日期的方法等,请参看Nachum Dershowitz和Edward M.Reingold编写的《Calendrical Calculations》(剑桥大学出版社,2001年)。
类库设计者决定将保存时间与给时间点命名分开。所以标准Java类库分别包含了两个类:一个是用来表示时间点的Date类;另一个是用来表示大家熟悉的日历表示法的GregorianCalendar类。事实上,GregorianCalendar类扩展了一个更加通用的Calendar类,这个类描述了日历的一般属性。标准Java库还包含泰国佛历和日本黄历的实现。
将时间与日历分开是一种很好的面向对象设计。通常,最好使用不同的类表示不同的概念。
Date类只提供了少量的方法用来比较两个时间点。例如before和after方法分别表示一个时间点是否早于另一个时间点,或者晚于另一个时间点。
注释:实际上,Date类还有getDay、getMonth以及getYear等方法,然而并不推荐使用这些方法。当类库设计者意识到某个方法不应该存在时,就把它标记为不鼓励使用。
当类库的设计者意识到单独设计日历类更有实际意义之前,这些方法就已经是Date类的一部分了。引入日历类之后,Date类中的这些方法被标明为不鼓励使用,虽然在程序中仍然可以使用它们,但是如果这样做,编译时会出现警告。最好还是不要使用这部分方法,它们有可能会从未来的类库版本中删去。
GregorianCalendar类所包含的方法要比Date类多得多。特别是有几个很有用的构造器。表达式
构造一个新对象,用于表示对象构造时的日期和时间。
另外,还可以通过提供年、月、日构造一个表示某个特定日期午夜的日历对象:
有些怪异的是,月份从0开始计数。因此11表示十二月。为了清晰起见,也可以使用常量,如:Calendar.DECEMBER。
还可以设置时间:
当然,常常希望将构造的对象存储在对象变量中:
GregorianCalendar类封装了实例域,这些实例域保存着设置的日期信息。不查看源代码不可能知道日期在类中的具体表达方式。当然,这一点并不重要,重要的是要知道类向外界开放的方法。