基本概念
时区(TimeZone)
时区一般指理论时区,它以能被15整除
的经线
为中心,向东西两侧延伸7.5°,即每15°一个时区。时区的时间采用其中央经线的地方时,相邻时区时差为一个小时,共24个时区
。其中,以本初子午线(经度0°)为中央经线的时区为零时区。
格林尼治标准时间(GMT)
格林尼治标准时间(GMT, 旧称格林尼治平均时间)的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。由于地球🌏每天的自转并不是匀速的,因此GMT实际上是有细微误差的,正因为这样,它已经逐渐被协调世界时(UTC)取代。
协调世界时(UTC)
协调世界时(UTC)又称作世界协调时间、世界协调时。它基于国际原子时,通过不规则地加入闰秒来抵消地球自转变慢带来的影响。
UTC 与 GMT 的差值极小,在日常生活中可以互换,但在高精度的科学研究中,GMT 已不再被认同。
北京时间(CST, 又称中国标准时间) 为 UTC +8
Unix时间戳(Unix timestamp)
Unix时间戳也作Unix时间(Unix time)、POSIX时间(POSIX time)等,是Unix或类Unix系统使用的时间表示方式,其值为UTC 1970-01-01 00:00:00至今的总秒数
,不考虑闰秒。
JDK8 以前
Date
Date是第一代时间类,自 JDK1.0 引入。
Date 本身没有时区的概念,因此不支持配置时区,它的toString()
、toLocaleString()
、toGMTString()
方法使用默认的Locale
、TimeZone
对当前时间做解析:
1 | Date date = new Date(); |
Calendar
Calendar是Date
的升级版,自 JDK1.1 引入。
相比于Date
,Calendar
主要有两大优势:
- 提供了更丰富的日期运算方法
- 支持配置时区
1 | Calendar calendar = Calendar.getInstance(); |
DateFormat
DateFormat用来做时间和字符串之间的转换,可以通过DateFormat.getDateInstance()
、DateFormat.getTimeInstance()
等方式获取实例。一般情况下,我们更倾向于直接使用SimpleDateFormat:
1 | String pattern = "GGG yyyy MMMMM dd EEE hh:mm aaa"; |
DateFormat
支持配置Locale
和TimeZone
:
- Locale: 设置表达格式。上面的例子中,中式表达和美式表达在部分字段有区别。
- TimeZone: 设置时区。
👿 使用DateFormat
时,最好使用严格的日期解析模式:
1 | DateFormat.setLenient(false); // 宽松模式,默认为true |
😞Bad Code
1 | String pattern = "yyyy-MM-dd"; |
外部传入错误的2020-02-30
,自动解析为2020-03-01
😘Good Code
1 | String pattern = "yyyy-MM-dd"; |
外部传入错误的2020-02-30
,代码执行报错:
1 | Exception in thread "main" java.text.ParseException: Unparseable date: "2020-02-30" |
这样一来,只要在代码中及时捕获异常,就能准确拦截错误的输入,保证程序正常运行。
JDK8
在 JDK8 中,引入了 LocalDate、LocalTime、LocalDateTime、Instant、Clock 等新的时间类,由于目前还未深入使用,暂时不做说明。 :D