热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaCalendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(3)Date

本章主要介绍Date类,并通过示例学习如何使用它。最后,讲解一下UTC、GMT和时区的关系。Date介绍Date定义publicclassDateimplementsj

 

本章主要介绍Date类,并通过示例学习如何使用它。最后,讲解一下UTC、GMT和时区的关系。

 


Date 介绍

Date 定义

public class Date implements java.io.Serializable, Cloneable, Comparable {}

Date 是表示时间的类
一个Date对象表示一个特定的瞬间,能精确到毫秒。我们可以通过这个特定的瞬间,来获取到Date对应的“年、月、日、时、分、秒”。反之亦然,我们也可以通过设置Date的“年、月、日、时、分、秒”等信息,来改变Date所指定的特定瞬间。
除了“年月日时分秒”等信息之外,Data也允许格式化和解析日期字符串。即,我们可以定义一个字符串,这个字符串包含时间信息,然后将字符串通过Date来解析,从而得到相应的Date对象。

在 JDK 1.1 之前,通常是通过Data操作“年月日时分秒”。不过,由于Date的相关 API 不易于实现国际化。从 JDK 1.1 开始,应该使用 Calendar 类来操作“年月日时分秒”,同时可以通过 DateFormat 类来格式化和解析日期字符串。Date 中的相应方法已废弃。

 

Date和Calendar相互转换

(01) Date转换为Calendar

// 新建date,且日期/时间为2013-09-19 14:22:30
Date date = new Date(113, 8, 19, 14, 22, 30);
// 新建Calendar对象,并设置日期为date
Calendar cal = Calendar.getInstance();
cal.setTime(date);

(02) Calendar换为Date

// 新建Calendar对象
Calendar cal = Calendar.getInstance();
// 获取Calendar对应的Date
Date date = cal.getTime();

 

Date 函数列表

Date 共包含下面5个构造函数

// Date构造函数一:传入“年、月、日”
// (01) 年 -- 减 1900 的年份。若要设为1988,则“年”应该是88。
// (02) 月 -- 0-11 的月份。0是一月,1是二月,依次类推。
// (03) 日 -- 1-31 之间的某一天。
Date(int year, int month, int day)

// Date构造函数二:传入“年、月、日、时、分”
// (01) 年 -- 减 1900 的年份。若要设为1988,则“年”应该是88。
// (02) 月 -- 0-11 的月份。0是一月,1是二月,依次类推。
// (03) 日 -- 1-31 之间的某一天。
// (04) 时 -- 0-23 之间的小时数。
// (05) 分 -- 0-59 之间的分钟数。
Date(int year, int month, int day, int hour, int minute)

// Date构造函数三:传入“年、月、日、时、分、秒”
// (01) 年 -- 减 1900 的年份。若要设为1988,则“年”应该是88。
// (02) 月 -- 0-11 的月份。0是一月,1是二月,依次类推。
// (03) 日 -- 1-31 之间的某一天。
// (04) 时 -- 0-23 之间的小时数。
// (05) 分 -- 0-59 之间的分钟数。
// (06) 秒 -- 0-59 之间的秒钟数。
Date(int year, int month, int day, int hour, int minute, int second)

// Date构造函数四:传入“毫秒”。 毫秒 = “目标时间” - “1970-01-01 00:00:00 GMT”
Date(long milliseconds)

// Date构造函数五:传入“字符串”。
Date(String string)

Date的操作API

// 根据参数确定日期和时间。这些参数被解释为年份、月份、月中某一天、一天中的某一小时、小时中某一分钟和分钟中的某一秒。
static long UTC(int year, int month, int day, int hour, int minute, int second)
// 此日期是否在指定日期之后。
boolean after(Date date)
// 此日期是否在指定日期之前
boolean before(Date date)
// 返回此对象的副本。
Object clone()
// 比较两个日期的顺序。
int compareTo(Date date)
// 比较两个日期是否相等。
boolean equals(Object object)
// 返回此 Date 对象表示的月份中的某一天。返回的值在 1 和 31 之间,表示包含或开始于此 Date 对象表示的时间的月份中的某一天(用本地时区进行解释)。
int getDate()
// 返回此日期表示的周中的某一天。返回值 (0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday) 表示一周中的某一天
int getDay()
// 返回此 Date 对象表示的小时。返回值是一个数字(0 至 23)
int getHours()
// 返回此日期所表示的小时已经过去的分钟数(用本地时区进行解释)。返回值在 0 和 59 之间。
int getMinutes()
// 返回表示月份的数字,该月份包含或开始于此 Date 对象所表示的瞬间。返回的值在 0 和 11 之间。0为一月,1为二月,依次类推。
int getMonth()
// 返回此日期所表示的分钟已经过去的秒数。返回的值在 0 和 61 之间。值 60 和 61 只可能发生在考虑了闰秒的 Java 虚拟机上。
int getSeconds()
// 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
long getTime()
// 返回相对于 UTC(相应于此 Date 对象表示的时间)的本地时区的偏移量(以分钟为单位)。
int getTimezoneOffset()
// 返回一个值,此值是从包含或开始于此 Date 对象表示的瞬间的年份减去 1900 的结果(用本地时区进行解释)。
int getYear()
// 哈希值
int hashCode()
// 把字符串 s 解释为日期和时间的表示形式。
static long parse(String string)
// 把此 Date 对象的月份中的某一天设置为指定值。
void setDate(int day)
// 把此 Date 对象的小时设置为指定值。
void setHours(int hour)
// 把此 Date 对象的分钟数设置为指定值。
void setMinutes(int minute)
// 把此日期的月份设置为指定值。0为一月,1为二月,依次类推。
void setMonth(int month)
// 把此 Date 的秒数设置为指定值。
void setSeconds(int second)
// 设置此 Date 对象,以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点。
void setTime(long milliseconds)
// 把此 Date 对象的年份设置为指定的值加 1900。
void setYear(int year)
// 返回GMT字符串
String toGMTString()
// 返回本地字符串
String toLocaleString()
// 返回字符串
String toString()

 

 


Date示例

下面我们通过示例学习使用Date的API。
源码如下(DateTest.java):

  1 import java.util.Date;
2 import java.util.Calendar;
3
4 /**
5 * java Date类的测试程序
6 *
7 * 注意几点:
8 * (01) Date中的“年” -- 读取/设置 到的年份值=“‘时间年份’ - 1900年”
9 * (02) Date中的“月” -- 0是一月,1是二月,2是三月,依次类推。
10 * (03) Date中的“星期几” -- 1是周日,2是周一,3是周二,依次类推。
11 *
12 * @author skywang
13 */
14 public class DateTest {
15
16 public static void main(String[] args) {
17
18 // 测试Date的构造函数:Date共有5类构造函数
19 testDateConstructor();
20
21 // 测试Date类的“设置”、“读取”函数
22 testDateSet();
23
24 // 测试Date类的before(), after(), compareTo(), equals(), clone(), parse()等接口
25 testOtherDateAPIs();
26 }
27
28 /**
29 * 测试Date的构造函数:Date共有5类构造函数
30 */
31 private static void testDateConstructor() {
32
33 Date date;
34
35 // Date构造函数一:传入“年、月、日”。
36 // 参数说明
37 // (01) 年 -- 减 1900 的年份。若要设为1988,则“年”应该是88。
38 // (02) 月 -- 0-11 的月份。0是一月,1是二月,依次类推。
39 // (03) 日 -- 1-31 之间的某一天。
40 // 设置时间为“1988-08-08”
41 date = new Date(88,7,8);
42 System.out.printf("Constructor-1 : %s\n", tostring(date));
43
44 // Date构造函数二:传入“年、月、日、时、分”
45 // (01) 年 -- 减 1900 的年份。若要设为1988,则“年”应该是88。
46 // (02) 月 -- 0-11 的月份。0是一月,1是二月,依次类推。
47 // (03) 日 -- 1-31 之间的某一天。
48 // (04) 时 -- 0-23 之间的小时数。
49 // (05) 分 -- 0-59 之间的分钟数。
50 // 设置时间为“1999-09-09 19:19”
51 date = new Date(99,8,9,19,19);
52 System.out.printf("Constructor-2 : %s\n", tostring(date));
53
54 // Date构造函数三:传入“年、月、日、时、分、秒”
55 // (01) 年 -- 减 1900 的年份。若要设为1988,则“年”应该是88。
56 // (02) 月 -- 0-11 的月份。0是一月,1是二月,依次类推。
57 // (03) 日 -- 1-31 之间的某一天。
58 // (04) 时 -- 0-23 之间的小时数。
59 // (05) 分 -- 0-59 之间的分钟数。
60 // (06) 秒 -- 0-59 之间的秒钟数。
61 date = new Date(100,10,10,20,10,10);
62 System.out.printf("Constructor-3 : %s\n", tostring(date));
63
64 // Date构造函数四:传入“毫秒”。 毫秒 = “目标时间” - “1970-01-01 00:00:00 GMT”
65 // 973858210000(ms) 对应时间 2000-10-10 8:10:10
66 date = new Date(973858210000l);
67 System.out.printf("Constructor-4 : %s\n", tostring(date));
68
69 // Date构造函数五:传入“字符串”。可以为以下几种格式:
70 // (注意,year值 = “实际年份-1900”)
71 // 1955-08-12 13:30:00
72 date = new Date("Sat, 12 Aug 95 13:30:00 GMT");
73 System.out.printf("Constructor-5.1: %s\n", tostring(date));
74 // 1955-08-12 13:30:00
75 date = new Date("12 Aug 95 13:30:00");
76 System.out.printf("Constructor-5.2: %s\n", tostring(date));
77 // 1955-08-12
78 date = new Date("12 Aug 95");
79 System.out.printf("Constructor-5.3: %s\n", tostring(date));
80 }
81
82 /**
83 * 测试Date类的“读取”函数
84 */
85 private static void testGet(Date date) {
86 // “年”。减 1900 的年份。若为1988,则“年”是88。
87 int year = date.getYear();
88 // “月”。 0-11 的月份。0是一月,1是二月,依次类推。
89 int mOnth= date.getMonth();
90 // “日”
91 int day = date.getDate();
92 // “时”
93 int hour = date.getHours();
94 // “分”
95 int minute = date.getMinutes();
96 // “秒”
97 int secOnd= date.getSeconds();
98 // “星期(几)”。 周日是1,周一是2,周二是3,依次类推。
99 int weekday = date.getDay();
100 // “毫秒”。毫秒 = “目标时间” - “1970-01-01 00:00:00 GMT”
101 long millis = date.getTime();
102 // “时区偏移”。相对于 UTC 的本地时区的偏移量(以分钟为单位)。
103 int timezOneoffset= date.getTimezoneOffset();
104
105 //System.out.printf("\t!!!date get is: %s\n", tostring(date));
106 System.out.println("\t!!!get date: "+year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second+"\t"+millis+"(ms)");
107 }
108
109
110 /**
111 * 测试Date类的“设置”函数
112 */
113 private static void testDateSet() {
114 // 新建date
115 Date date = new Date(99,8,9);
116
117 // 设置Date为“2013-09-19 15:28:30”
118 // 设为“2013年”。传入值是“‘目标年份’ - ‘1900 的年份’”
119 date.setYear(113);
120 // 设为“8月”,传入的参数应该是8。因为,一月是0,二月是1,依次类推。
121 date.setMonth(8);
122 // 设为“19日”
123 date.setDate(19);
124 // 设为“15”(上午)。采用的24时制;因此,若要设为上午3点,应该传入参数3。
125 date.setHours(11);
126 // 设为“28分”
127 date.setMinutes(28);
128 // 设为“30秒”
129 date.setSeconds(30);
130 System.out.printf("new date-01 is: %s\n", tostring(date));
131
132 // 测试Date的获取函数
133 testGet(date);
134
135 // 设为“毫秒”,1379561310000(ms) 对应的时间是“2013-09-19 15:28:30”
136 date.setTime(1379561310000l);
137 System.out.printf("new date-02 is: %s\n", tostring(date));
138 }
139
140 /**
141 * 测试Date类的before(), after(), compareTo(), equals(), clone(), parse()等接口
142 */
143 private static void testOtherDateAPIs() {
144 // 初始化d1=2008-05-12, d2=2009-03-15。
145 Date d1 = new Date(108,4,12);
146 System.out.printf("\nd1 is: %s\n", tostring(d1));
147 Date d2 = new Date(109,2,15);
148 System.out.printf("d2 is: %s\n", tostring(d2));
149
150 // 克隆
151 Date d3 = (Date) d1.clone();
152 System.out.printf("clone of d1 is: %s\n", tostring(d3));
153
154 // d1 是否早于 d2
155 boolean isBefore = d1.before(d2);
156 // d1 是否晚于 d2
157 boolean isAfter = d1.after(d2);
158 // d1 是否等于 d2
159 boolean isEquals = d1.after(d2);
160 // d1 和 d2 比较。
161 // 若d1 早于 d2,返回 -1
162 // 若d1 晚于 d2,返回 1
163 // 若d1 等于 d2,返回 0
164 int comp = d1.compareTo(d2);
165 System.out.printf("isBefore=%s, isAfter=%s, isEquals=%s, comp=%s\n",
166 isBefore, isAfter, isEquals, comp);
167
168 // parse接口
169 long millis = Date.parse("13 Mar 2009");
170 // (注意,通过这种方式设置Date,获取的Year值是“实际年份-1900”)
171 Date d4 = new Date(millis);
172 System.out.printf("millis=%s, d4=%s\n", millis, tostring(d4));
173 System.out.printf("d1.toGMTString()%s\n", d1.toGMTString());
174 System.out.printf("d1.toLocaleString()%s\n", d1.toLocaleString());
175 System.out.printf("d1.toString()%s\n", d1.toString());
176 }
177
178 /**
179 * 将date转换Calendar对象,并返回实际的年月日。
180 */
181 private static String tostring(Date date) {
182 // 获取Date对应的Calendar
183 Calendar cal = Calendar.getInstance();
184 cal.setTime(date);
185 int year = cal.get(Calendar.YEAR);
186 int mOnth= cal.get(Calendar.MONTH)+1;
187 int day = cal.get(Calendar.DATE);
188 int hour = cal.get(Calendar.HOUR);
189 int minute = cal.get(Calendar.MINUTE);
190 int secOnd= cal.get(Calendar.SECOND);
191 long millis = cal.getTimeInMillis();
192
193 return year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second+"\t"+millis+"(ms)";
194 }
195 }
View Code

 

 


GMT、UTC、时区的关系

 

      许多人都知道两地时间表简称为GMT或UTC,而世界时区表则通称为World Time,那么GMT与UTC的实质原意又是为何?世界时区又是怎么区分的?面盘上密密麻麻的英文单字代表着什么意义与作用呢?这些都是新手在接触两地时间表或世界时区表时,脑海中所不断浮现的种种疑问,以下将带您一探时区奥妙的究竟。

 

世界时区及国际换日线示意图

 

 

 

 


全球24个时区的划分 
      相较于两地时间表,可以显示世界各时区时间和地名的世界时区表(World Time),就显得精密与复杂多了,通常世界时区表的表盘上会标示着全球24个时区的城市名称,但究竟这24个时区是如何产生的?过去世界各地原本各自订定当地时间,但随着交通和电讯的发达,各地交流日益频繁,不同的地方时间,造成许多困扰,于是在西元1884年的国际会议上制定了全球性的标准时,明定以英国伦敦格林威治这个地方为零度经线的起点(亦称为本初子午线),并以地球由西向东每24小时自转一周360°,订定每隔经度15°,时差1小时。而每15°的经线则称为该时区的中央经线,将全球划分为24个时区,其中包含23个整时区及180°经线左右两侧的2个半时区。就全球的时间来看,东经的时间比西经要早,也就是如果格林威治时间是中午12时,则中央经线15°E的时区为下午1时,中央经线30°E时区的时间为下午2时;反之,中央经线15°W的时区时间为上午11时,中央经线30°W时区的时间为上午10时。以台湾为例,台湾位于东经121°,换算后与格林威治就有8小时的时差。如果两人同时从格林威治的0°各往东、西方前进,当他们在经线180°时,就会相差24小时,所以经线180°被定为国际换日线,由西向东通过此线时日期要减去一日,反之,若由东向西则要增加一日。

 

格林威治标准时间GMT
      十七世纪,格林威治皇家天文台为了海上霸权的扩张计画而进行天体观测。1675年旧皇家观测所(Old Royal Observatory) 正式成立,到了1884年决定以通过格林威治的子午线作为划分地球东西两半球的经度零度。观测所门口墙上有一个标志24小时的时钟,显示当下的时间,对全球而言,这里所设定的时间是世界时间参考点,全球都以格林威治的时间作为标准来设定时间,这就是我们耳熟能详的「格林威治标准时间」(Greenwich Mean Time,简称G.M.T.)的由来,标示在手表上,则代表此表具有两地时间功能,也就是同时可以显示原居地和另一个国度的时间。

 

世界协调时间UTC
      多数的两地时间表都以GMT来表示,但也有些两地时间表上看不到GMT字样,出现的反而是UTC这3个英文字母,究竟何谓UTC?事实上,UTC指的是Coordinated Universal Time- 世界协调时间(又称世界标准时间、世界统一时间),是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以基本上UTC的本质强调的是比GMT更为精确的世界时间标准,不过对于现行表款来说,GMT与UTC的功能与精确度是没有差别的。

 

夏日节约时间DST
      所谓「夏日节约时间」Daylight Saving Time(简称D.S.T.),是指在夏天太阳升起的比较早时,将时钟拨快一小时,以提早日光的使用,在英国则称为夏令时间(Summer Time)。这个构想于1784年由美国班杰明·富兰克林提出来,1915年德国成为第一个正式实施夏令日光节约时间的国家,以削减灯光照明和耗电开支。自此以后,全球以欧洲和北美为主的约70个国家都引用这个做法。目前被划分成两个时区的印度也正在商讨是否全国该统一实行夏令日光节约时间。欧洲手机上也有很多GSM系统的基地台,除了会传送当地时间外也包括夏令日光节约时间,做为手机的时间标准,使用者可以自行决定要开启或关闭。值得注意的是,某些国家有实施「夏日节约时间」的制度,出国时别忘了跟随当地习惯在表上调整一下,这可是机械表没有的功能设计哦!

 

 


更多内容

Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(1) Calendar

Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(2) 自己封装的Calendar接口

Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(3) Date

Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(4) DateFormat

Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(5) SimpleDateFormat

Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(6) Locale

Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(7) TimeZone

 


推荐阅读
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
author-avatar
我是赵晓霆
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有