20145306张文锦

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

20145306 《Java程序设计》第7周学习总结

教材学习内容总结

第十三章

一、认识时间与日期

1.时间的度量

在正式认识Java提供了哪些时间处理API之前,得先来了解一些时间、日期的历史问题,这样你才会知道,时间日期确实是个很复杂的问题,而使用程 序来处理时间日期,也不仅仅是使用API的问题格林威治标准时间:格林威治标准时间简称GMT时间,一开始是参考自格林威治皇家天文台的标准太阳时间,格 林威治标准时间的正午是太阳抵达天空最高点之时,格林威治标准时间常被不严谨的当成是UTC时间。世界时:世界时是借由观测远方星体跨过子午线而得,也称 UT,这会比观察太阳来得准确一些。1972年引入UTC之前,GMT与UT是相同的。国际原子时:虽然观察远方星体会比观察太阳来得准确,不过UT基本 上仍受地球自转速度影响而会有所误差。1967年定义的国际原子时(TAI),将秒的国际单位定义为铯原子辐射振动9192631770周耗费的时间,时 间从UT的1958年开始同步。世界协调时间:由于基于铯原子振动定义的秒长是固定的,然而地球自转会越来越慢,这会使得实际上 TAI时间会不断超前基于地球自转的UT系列时间,为了保持TAI与UT时间不要差距过大,因而提出了具有折衷修正版本的世界协调时间(UTC)。 Unix时间:Unix系统的时间表示法,定义为UTC时间1970年1月1日00:00:00为起点而经过的秒数,不考虑闰秒修正,用以表达时间轴上某 一瞬间。epoch:某个特定时代的开始,时间轴上某一瞬间。例如java.util.Date封装的时间信息,就是January 1,1970,00:00:00 GMT经过的毫秒数,可以简称为epoch毫秒数。就目前来说,即使标注为GMT,实际上谈到的时间指的是UTC时间。秒的单位定义是基于TAI,也就是 铯原子辐射振动次数。Unix时间是1970年1月1日00:00:00为起点而经过的秒数,不考虑闰秒。

2.年历简介

度量时间是一回事,表达日期又是另一回事,前面谈到的时间起点,都是使用公历,中文世界又常称为阳历,在谈到公历之前,先来看看其他的历法。儒略历 是现今公历的前身,用来取代罗马历。儒略历修正了罗马历隔三年设置一闰年的错误,改采四年一润。格里高利历改革了儒略历,将儒略历1582年10月4日星 期四的隔天,定为格里高利历1582年10月15日星期五。在一些相对来说较新的时间日期API应用场合中,你可能会看到ISO 8601,严格来说ISO 8601并非年历系统,而是时间日期表示方法的标准,用以统一时间日期的数据交换格式,ISO 8601在数据定义上大部分与格里高利历相同,不过还是有微小差别。在ISO 8601的定义中,19世纪是指1900年至1999年(包含该年),而格里高利历的19世纪是指1801年至1900年(包含该年)。

3.认识时区

由于地球是圆的,基本上一边白天另一边就是夜晚,为了让人们对时间的认知符合作息,因而设置了UTC偏移,大致上来说,经度每15度是偏移一个小 时,考虑了UTC偏移的时间表示上,通常会标识Z符号。不过有些国家的领土横跨的经度很大,一个国家有多个时间反而造成困扰,因而不采取每15度偏移一小 时的做法,像美国仅有4个时区,而中国,印度只采用单一时区。一年的毫秒数绝对不是单纯的 365X24X60X60X1000,更不要基于这类错误的观念来进行时间与日期运算。

二、认识Date与Calendar

1.时间轴上瞬间的Date

如果想要取得系统时间,方法之一是使用System.currentTimeMillis()方法,返回的是long类型整数,代表1970年1月 1日0时0分0秒0毫秒至今经过的毫秒数,也就是时间起点与前面谈到的Unix时间起点是相同的。不过以此方法取得的是机器的时间观点,代表着时间轴上某 一瞬间,这一长串的epoch毫秒数不是人类的时间观点,对人类来说没有阅读上的意义。Date有两个构造函数可以使用,一个可使用epoch毫秒数构 建,另一个为无自变量构造函数,内部亦是使用System.currentTimeMillis()取得epoch毫秒数,调用getTime()可取得 内部保存的epoch毫秒数值。getTime()之外的getXXX()方法都废弃了,setTime()之外的setXXX()方法也都废弃了。 Date实例基本上建议只用来当作时间轴上的某一瞬间,也就是1970年1月1日0时0分0秒至今经过的毫秒数,其他对时间日期字段的设定与取得,建议通 过Calendar来执行。

2.格式化时间日期的DateFormat

有关字符串时间格式的处理,职责落到了java.text.DateFormat身上,DateFormat是个抽象类,其操作类是 java.text.SimpleDateFormat,你可以直接构建SimpleDateFormat实例,或是使用DateFormat的 getDateInstance()、getTimeInstance()、getDateTimeInstance()等静态方法。 SimpleDateFormat还有个parse()方法,可以按构建SimpleDateFormat时指定的格式,将指定的字符串剖析为Date实 例。

3.处理时间日期的Calendar

Date现在建议作为时间轴上的瞬时代表,要格式化时间日期则通过DateFormat,如果想要取得某个时间日期信息,或者是对时间日期进行操 作,可以使用Calendar实例。Calendar是个抽象类,java.util.GregorianCalendar是其子类,操作了儒略历与格里 高利历的混合历,通过Calendar的getInstance()取得的Calendar实例,默认就是取得GregorianCalendar实例。 如果想要比较两个Calendar的时间日期先后,可以使用after()或before()方法。

4.设定TimeZone

前面在使用Calendar时,并没有使用时区信息,这会使用默认时区,你可以使用java.util.TimeZone的getDefault()来取得默认时区信息。

三、JDK8新时间日期API

1.机器时间观点的API

Date实例真正代表的并不是日期,最接近的概念应该是时间轴上特定的一瞬间,时间精度是毫秒,也就是UTC时间1970年1月1日0时0分0毫秒 至某个特定瞬时的毫秒差。Date名称看来像是人类的时间概念,实际上却是机器的时间概念。真正可靠的信息只有内含的epoch毫秒数。所以如果你取得 Date实例,下一步获取时间信息应该是通过Date的getTime()取得epoch毫秒数。JDK8新时间日期处理API中,最重要的就是清楚的将 机器对时间的概念与人类对时间的概念分隔开来。

2.人类时间观点的API

对于片段的日期时间,JDK8新时间与日期API有LocalDateTime()、LocalDate()、LocalTime()等类来定义,这些类基于ISO 8601年历系统,是不具时区的时间与日期定义。

在新的时间与日期API中,UTC偏移量与时区的概念是分开的,offsetDateTime单纯代表UTC偏移量,使用ISO 8601。如果只想表示2014年,可以使用Year,如果想表示2014/5,可以使用YearMonth,如果只想表示5月,可以使用Month,如 果想表示5/4,可以使用MonthDay,其中Month是enum型,如果你想要取得代表月份的数字,不要使用oridinal()方法,因为 oridinal()是enum在定义时的顺序,从0开始,想要取得代表月份的数要通过getValue()方法。

posted on 2016-04-17 23:34  20145306张文锦  阅读(135)  评论(1编辑  收藏  举报