Making Sense of Java's Dates
by Philipp K. Janert, Ph.D. translated by humx
简介
在计算机程序中精确的处理日期是困难的。不仅有显而易见的(英语: January, 法语: Janvier, 德语: Januar, 等)国际化需求, 而且得考虑不同的日期系统(并非所有的文化都用基督耶稣的生日作为纪年的开始)。如有高精度或非常大规模的时间需要被处理, 就有额外的方面需要被注意,比如闰秒或时间系统的变化。(公历(阳历, 格里高利历法)在西方被普遍接受是在1582年,但并非所有的国家在同一天接受!)
尽管有关于闰秒, 时区, 夏令时, 阴历的问题, 度量时间却是一个非常简单的概念: 时间的进行是线性的很容易被忽略。一旦时间轴的区域被定义, 任何时间点被从起点时间的流逝就可以确定。这和地理位置或当地时区是独立的 – 对任意指定的时间点, 对任意地区, 从起点的过程是相同的(忽略相对论的矫正)。
可当我们试图根据某些日历解释这一时间点的时候困难来了, 比如, 根据月, 日, 或者年来表示它。在这一步上地理信息变得相关: 在时间上的同一个点对应不同的天的某一时间, 依赖于区域 (比如: 时区)。基于解释日期的修正经常是必要的(今天一个月以后是哪一天?) 并且增加了额外的困难: 上溢和下溢(12月15号的后一个月是下一年), 且不明确(1月30号后的一个月是哪一天?).
在最初的JDK 1.0, 一个时间点, 通过把它解释为java.util.Date类, 它被计算在一起来表示. 虽然相对容易处理, 但它并不支持国际化; 从JDK 1.1.4 或JDK 1.1.5, 多样的负责处理日期的职责被分配到以下类中:
|
java.util.Date |
代表一个时间点. |
|
abstract java.util.Calendar |
解释和处理Date. |
|
abstract java.util.TimeZone |
代表一个任意的从格林威治的偏移量, 也包含了适用于夏令时(daylight savings rules)的信息. |
|
abstract java.text.DateFormat extends java.text.Format |
变形到格式良好的, 可打印的String, 反之亦然. |
|
java.text.DateFormatSymbols |
月份, 星期等的翻译, 作为从Locale取得信息的一种替代选择. |
|
java.sql.Date extends java.util.Date |
代表时间点, 同时为了在sql语句中使用也包含适当的格式. |
注意: DateFormat 和相关的类在java.text.*包. 所有的java.sql.*包中日期处理相关类继承了java.util.Date类. 所有的其它类在java.util.*包中.
这些"新"类来自三个分离的继承层次, 其顶层类(Calendar, TimeZone, and DateFormat)是抽象的. 针对每一个抽象类, Java标准类库提供了一个具体的实现.
java.util.Date
类java.util.Date代表一个时间点. 在许多应用中, 此种抽象被称为"TimeStamp." 在标准的Java类库实现中, 这个时间点代表Unix纪元January 1, 1970, 00:00:00 GMT开始的毫秒数. 因而概念上来说, 这个类是long的简单封装.
根据此种解释, 类中仅有的没有过期的(除了那些毫秒数的get和set方法)是那些排序方法.
这个类依靠System.currentTimeMillis() 来取得当前的时间点. 因此它的准确度和精度由System的实现和它所调用底层(本质是操作系统)决定.






