Java时区问题

遇到的问题:

   1.背景:项目是做印尼的业务,所以经常遇到时区问题,timezone搞不好好容易出错,尤其是还款时间问题

    2.经过:同事用postman在mock的时候,传的repaidTime = "2020-09-02T11:26:48.289Z"(UTC时间,与北京相差8小时)

    3.问题: 日志里输出log时,发现时间变成了  repaidTime = Wed Sep 02 19:26:48 WIB 2020,多了8小时

 

然后查看了参数,发现时间的格式需要探究一下,所以引用了以下文章(https://www.cnblogs.com/champyin/p/12767852.html)

 

前言

格林威治时间、世界时、祖鲁时间、GMT、UTC、跨时区、夏令时,这些眼花缭乱的时间术语,我们可能都不陌生,但是真正遇到问题,可能又不那么确定,不得不再去查一查,处理完可能过段时间又忘记。今天,我们彻底来梳理一下它们。

一、GMT

什么是GMT

GMT(Greenwich Mean Time), 格林威治平时(也称格林威治时间)。

它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午12点。

GMT的历史

格林威治皇家天文台为了海上霸权的扩张计划,在十七世纪就开始进行天体观测。为了天文观测,选择了穿过英国伦敦格林威治天文台子午仪中心的一条经线作为零度参考线,这条线,简称格林威治子午线。

1884年10月在美国华盛顿召开了一个国际子午线会议,该会议将格林威治子午线设定为本初子午线,并将格林威治平时 (GMT, Greenwich Mean Time) 作为世界时间标准(UT, Universal Time)。由此也确定了全球24小时自然时区的划分,所有时区都以和 GMT 之间的偏移量做为参考。

1972年之前,格林威治时间(GMT)一直是世界时间的标准。1972年之后,GMT 不再是一个时间标准了。

二、UTC

什么是UTC

UTC(Coodinated Universal Time),协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。

UTC 是现在全球通用的时间标准,全球各地都同意将各自的时间进行同步协调。UTC 时间是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以秒为单位的国际原子时所综合精算而成。

在军事中,协调世界时会使用“Z”来表示。又由于Z在无线电联络中使用“Zulu”作代称,协调世界时也会被称为"Zulu time"。

UTC 由两部分构成:

  • 原子时间(TAI, International Atomic Time):
    结合了全球400个所有的原子钟而得到的时间,它决定了我们每个人的钟表中,时间流动的速度。

  • 世界时间(UT, Universal Time):
    也称天文时间,或太阳时,他的依据是地球的自转,我们用它来确定多少原子时,对应于一个地球日的时间长度。

UTC的历史

1960年,国际无线电咨询委员会规范统一了 UTC 的概念,并在次年投入实际使用。

“Coordinated Universal Time”这个名字则在1967年才被正式采纳。

1967年以前, UTC被数次调整过,原因是要使用闰秒(leap second)来将 UTC 与地球自转时间进行统一。

三、GMT vs UTC

GMT是前世界标准时,UTC是现世界标准时。
UTC 比 GMT更精准,以原子时计时,适应现代社会的精确计时。
但在不需要精确到秒的情况下,二者可以视为等同。
每年格林尼治天文台会发调时信息,基于UTC。

四、时区

随着火车铁路与其他交通和通讯工具的发展,以及全球化贸易的推动,各地使用各自的当地太阳时间带来了时间不统一的问题,在19世纪催生了统一时间标准的需求,时区由此诞生。

时区是如何定义的

从格林威治本初子午线起,经度每向东或者向西间隔15°,就划分一个时区,在这个区域内,大家使用同样的标准时间。

但实际上,为了照顾到行政上的方便,常将1个国家或1个省份划在一起。所以时区并不严格按南北直线来划分,而是按自然条件来划分。另外:由于目前,国际上并没有一个批准各国更改时区的机构。一些国家会由于特定原因改变自己的时区。

全球共分为24个标准时区,相邻时区的时间相差一个小时。

time-timezone.png

在不同地区,同一个时区往往会有很多个不同的时区名称,因为名称中通常会包含该国该地区的地理信息。在夏令时期间,当地的时区名称及字母缩写会有所变化(通常会包含“daylight”或“summer”字样)。

例如美国东部标准时间叫:EST,Estern Standard Time;而东部夏令时间叫:EDT,Estern Daylight Time。

想查看世界所有时区的名字可以访问这个网站:
https://www.timeanddate.com/time/zones/

四、夏令时

什么是夏令时

DST(Daylight Saving Time),夏令时又称夏季时间,或者夏时制。

它是为节约能源而人为规定地方时间的制度。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。

全球约40%的国家在夏季使用夏令时,其他国家则全年只使用标准时间。标准时间在有的国家也因此被相应地称为冬季时间。

在施行夏令时的国家,一年里面有一天只有23小时(夏令时开始那一天),有一天有25小时(夏令时结束那一天),其他时间每天都是24小时。

time-daylight-time.jpg

绿色部分为2019年统计的在全球施行冬夏令时的国家和地区。

夏令时的历史

1784年,美国驻法国大使本杰明·富兰克林(Benjamin Franklin)提出“日光节约时间制”。1908年,英国建筑师威廉·维莱特(William Willett)再次提出,但当时该提案并未被采纳。

1916年,处于一战时期的德国政府下令将时钟推至一个小时后,通过获得额外一小时的日光来节省战争所需的煤炭,成为第一个实行夏时制的国家。随后,英法俄美四个一战参战国纷纷效仿。

美国在一战结束后于1919年取消夏时制,但在1942年二战时,美国重新启动夏令时制,1966年正式立法确定永久使用。1973至1975年石油危机爆发期间,美国连续两年延长夏令时制,以节省石油。

欧洲大部分国家则是从1976年——第四次中东战争导致首次石油危机(1973年)的3年后才开始施行夏令时制。

1986年4月,中国国务院办公厅发出《在全国范围内实行夏时制的通知》,要求全民早睡早起节约能源:每年4月中旬的第一个星期日2时,将时钟拨快一小时;10月中旬第一个星期日的2时,再将时钟拨慢一小时。但此夏令时只实行了6年,在1992年停止施行,主因是中国东西地域广阔却只奉行一个北京时间,实时夏令时制带来很多不切实际的反效果。

夏令时的争议

从过去的100多年来看,夏令时往往是在国家发生严重危机(如战争和能源短缺)的情况下才会受到青睐。而在相对和平的近10年里,这种时间制度则变得越来越不受欢迎。

它会使得人们的生物钟被扰乱,常常陷入睡眠不足的情况,不仅对人体健康有害、导致车祸,还会对旅游、航空领域造成极大的混乱。

另外,冬、夏令时究竟能否起到节能的作用,也仍有待商榷。美国一项截至2014年3月的研究表明,这种时间转换制度最多能在3、4月帮助美国减少1%的用电量,而美国国家标准局则认为,夏令时对用电量没有丝毫影响。

在俄罗斯,此前的一份报告也显示,夏令时帮助俄罗斯每年节约的电量,仅相当于两三个火力发电厂的发电量,十分的“鸡肋”。

去年(2019年)3月26日,作为全世界第一个提出并实行夏令时的国家,德国,在欧洲议会上以410比192的赞成票通过了取消冬、夏令时转换制提案,拟定于2021年4月起,所有欧盟国家不再实行冬、夏令时转换。待各成员国形成最终法案后,将选择永久使用夏令时时间或是冬令时时间。

五、本地时间

在日常生活中所使用的时间我们通常称之为本地时间。这个时间等于我们所在(或者所使用)时区内的当地时间,它由与世界标准时间(UTC)之间的偏移量来定义。这个偏移量可以表示为 UTC- 或 UTC+,后面接上偏移的小时和分钟数。

六、JavaScript中的Date

得到本地时间,在不同时区打印 new Date() ,输出的结果将会不一样:

new Date();

得到本地时间距 1970年1月1日午夜(GMT时间)之间的毫秒数:

new Date().getTime();

返回本地时间与 GMT 时间之间的时间差,以分钟为单位:

new Date().getTimezoneOffset();

如何在任何地方都能正确显示当地时间(只要知道该地的timezone):

//目标表时间,东八区
let timezone = 8;
//获取本地时间与格林威治时间的时间差(注意是分钟,记得转换)
const diff = new Date().getTimezoneOffset();
//根据本地时间和时间差获得格林威治时间
const absTime = new Date().getTime() + diff * 60 * 1000;
//根据格林威治时间和各地时区,得到各地时区的时间
let localTime = new Date(absTime + timeZone * 60 * 60 * 1000);
//处理夏令时(isDST为自己封装的处理方法)
if(isDST(localTime, country)) {
  localTime = new Date(absTime + (timeZone + 1) * 60 * 60 * 1000);
}
return localTime;

结语

以上分别从定义、来源等维度解释和扩展说明了GMT、UTC、时区和夏令时的概念、历史、意义,并在最后列举了这些概念在JS项目中的一个非常实用的应用。

简单地讲, GMT 是以前的世界时间标准;UTC 是现在在使用的世界时间标准;时区是基于格林威治子午线来偏移的,往东为正,往西为负;夏令时是地方时间制度,施行夏令时的地方,每年有2天很特殊(一天只有23个小时,另一天有25个小时)。

从源头上彻底了解了这些概念,将会让我们在处理与时间相关的问题时如虎添翼。

你可能感兴趣的:(后台)