用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

海大软件1102班    -  云代码空间

—— 你究竟输入什么了导致它崩溃?

Java Date, Calendar日期处理相关类分析

2013-01-11|3769阅||

摘要:在计算机程序中精确的处理日期是困难的。不仅有显而易见的(英语: january, 法语: janvier, 德语: januar, 等)国际化需求, 而且得考虑不同的日期系统(并非所有的文化都用基督耶稣的生日作为纪年的开始)。如有高精度或非常大规模的时间需要被处理, 就有额外的方

在计算机程序中精确的处理日期是困难的。不仅有显而易见的(英语: 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 
java.util.gregoriancalendar extends java.util.calendar 
解释和处理date. 

abstract java.util.timezone 
java.util.simpletimezone extends java.util.timezone 
代表一个任意的从格林威治的偏移量, 也包含了适用于夏令时(daylight savings rules)的信息. 

abstract java.text.dateformat extends java.text.format 
java.text.simpledateformat extends java.text.dateformat 
变形到格式良好的, 可打印的string, 反之亦然. 

java.text.dateformatsymbols 
月份, 星期等的翻译, 作为从locale取得信息的一种替代选择. 

java.sql.date extends java.util.date 
java.sql.time extends java.util.date 
java.sql.timestamp 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的实现和它所调用底层(本质是操作系统)决定. 

the java.util.date api 

在最初的 date类使用中名字和约定引起了无尽的混淆. 然而用0-11计算月, 从1900计算年的决定模仿了c标准类库的习惯, 调用函数 gettime()返回起始于unix纪元的毫秒数和 getdate()返回星期的决定显然是java类设计者自己的. 


java.util.calendar 

语义 

calendar代表一个时间点(一个"date"), 用以在特定的区域和时区适当的解释器. 每一个calendar 实例有一个包含了自纪元开始的代表时间点的long变量. 

这意味着calendar 不是一个(无状态) 变换者或解释器, 也不是一个修改dates的工厂. 它不支持如下方式: 

month interpreter.getmonth(inputdate) or 

date factory.addmonth(inputdate) 

instead, calendar实例必须被初始化到特定的date. 此calendar实例可以被修改或查询interpreted属性. 

奇怪的是, 此类的instances 总是被初始化为当前时间. 获得一个初始化为任意date的calendar 实例是不可能的—api强制程序员通过一系列的在实例上的方法调用, 比如settime(date)来显式的设置日期. 

访问interpreted 字段和类常量 

calendar类遵从一不常用的方式来访问interpreted date实例的单个字段