近期一个上马的项目涉及到国际化,其中一个点就是时间显示的问题,比如现在时间是 北京时间 2022-05-29 23:21:30,这个在国内显示没问题,如果在墨西哥显示呢,显然是不能用北京时间的,毕竟两者隔了十三个时区,这时对方才 2022-05-29 10:21:30 呢。

北京时间是东八区,墨西哥是西五区。

显然,时间国际化涉及到了时区概念,这里对时区做个简单的介绍。国际上规定,每隔 15° 划为一个时区,全球可分为 24 个时区。以本初子午线为基准,从西经 7.5° 到东经 7.5° 就是 GMT 0 时区。

东西经各 180°,那么 360/15= 24 个时区。

GMT,Greenwich Mean Time, 即格林尼(威)治标准时间。

一般来说,北京时间就是 GMT +8 时区的,即东八区,墨西哥时间是 GMT -5,即西五区。

其实,在国际上,GMT 是等同于 UTC 的。UTC(Coordinated Universal Time)又叫做协调世界时,也即是标准时间。UTC 是根据原子钟来计算时间,而 GMT 是根据地球的自转和公转来计算时间,也就是太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间就是中午12点。由于科技的进步,目前最先进的原子钟 50 亿年才误差 1 秒,而地球自转在大部分情况下其速度是越来越慢的,因此 UTC 时间更加精确。

UTC 是 GMT 的换算单位是 UTC = GMT + 0。因此 GMT +8 等同于 UTC +8

好了,铺垫就到此为止了,接下来就用 golang 代码演示下如何做到时间国际化。

其实,思路也很简单,就两步:

  • 一、获取时间戳;
  • 二、依据时区编码,从而计算 UTC 与 给定时区的时差。

时区编码文件放在 $GOROOT/lib/time/zoneinfo.zip 中,解压下,发现第一层都是目录,第二层和第一层相结合就是具体的时区编码,比如 America/Mexico_City。

还是以博文开头的时间为例,2022-05-29 23:21:30 对应的时间戳为 1653837690

package mainimport ("log""time"
)// GetTimeOffset 国际化时间戳偏移
func GetTimeOffset(timezone string, ts int64) (offset int) {var loc, _ = time.LoadLocation(timezone)_, offset = time.Unix(ts, 0).In(loc).Zone()return
}func main() {ts := int64(1653837690)offset := GetTimeOffset("America/Mexico_City", ts)log.Println(offset) // -18000
}

计算可知偏移量为 -18000 秒,ok,换算成时区就是 GMT -5 也就是 西五区了,此时,如果把偏移量和时间戳丢给前端渲染,由前端自己本地化时区转化为用户所在时区对应的时间即可。

var d = new Date("2022-05-29 23:21:30");
var utc = d.getTime() + (d.getTimezoneOffset() * 60000);
var nd = new Date(utc + (3600000 * -13));// 2022 4 29 2 21 30
console.log(nd.getFullYear(), nd.getMonth(), nd.getDate(), nd.getHours(),nd.getMinutes(),nd.getSeconds())

如果都是由后端计算并传值,前端显示的话,也简单,代码如下

package mainimport ("log""time"
)const DefaultDate = "2006-01-02 15:04:05"// FormatWithLocation 国际化时间戳转换字符串
func FormatWithLocation(timezone string, ts int64) string {lt, _ := time.LoadLocation(timezone)str := time.Unix(ts, 0).In(lt).Format(DefaultDate)return str
}// ParseWithLocation 国际化时间字符串转换时间戳
func ParseWithLocation(timezone string, timeStr string) int64 {l, _ := time.LoadLocation(timezone)lt, _ := time.ParseInLocation(DefaultDate, timeStr, l)return lt.Unix()
}func main() {// 北京时间str := "2022-05-29 23:21:30"// 注意,这里不要用 time.Parse 直接转时间戳,这个转的结果为 UTC 时间// 结果会默认加上时差,也就是多八个小时// 对应的时间戳ts := ParseWithLocation("Asia/Shanghai", str)// 获取最终的时间戳log.Println(FormatWithLocation("America/Mexico_City", ts)) // 2022-05-29 10:21:30}

最后,给个简单的 php 的实现方案。

<?phpfunction getGlobalDate($timezone, $timeStr) {return new DateTime($timeStr, new DateTimeZone($timezone));
}try {$date = getGlobalDate('Asia/Shanghai', '2022-05-29 23:21:30');$offsetBJ = $date->getOffset();$ts = $date->getTimestamp();$date = getGlobalDate('America/Mexico_City', '2022-05-29 23:21:30');$offsetMX = $date->getOffset();echo date('Y-m-d H:i:s', $ts - $offsetBJ + $offsetMX) . "\n"; // 2022-05-29 10:21:30} catch (Exception $e) {echo $e->getMessage();
}

【参考】

计算机时间到底是怎么来的?程序员必看的时间知识!
Golang Time包的本地化时区一次需求实现
UTC和GMT什么关系?
彻底弄懂GMT、UTC、时区和夏令时

golang 之时间国际化相关推荐

  1. golang 格式化时间成datetime

    Golang或者Beego,总需要往数据库里写datetime时间戳. Golang对时间格式支持并不理想. 先看一个例子: package main import ( "fmt" ...

  2. moment 时间国际化问题

    moment 时间国际化问题 moment国际化时间的设置方法 支持的语言类型 moment国际化时间的设置方法 支持的语言类型 af.js br.js en-gb.js fr-ch.js it.js ...

  3. golang日期时间格式format()

    format()函数格式化字符串,用了语句time.now().format("2015-11-12 12:00:00"),结果输出结果就是不能达到理想的结果,然后把golang文 ...

  4. php 产生国际时间,php时间国际化和本地转换

    发表于 2017-08-04 07:00:37 by 月小升 假如一个网站面临国际人群,那么可能分布在不同的 echo ''; date_default_timezone_set("UTC& ...

  5. mysql 时间国际化_日期时间处理和国际化相关

    日期/时间的国际化,不仅涉及到地理位置(Locale,比如星期.月份等日历本地化表示),还涉及到时区(TimeZone,针对UTC/GMT的偏移量).时区不仅是地理位置规定,更是政治规定,比如中国从地 ...

  6. golang实现时间轮

    golang原生定时器 http://c.biancheng.net/view/5723.html https://www.cyhone.com/articles/analysis-of-golang ...

  7. golang time 时间 加减法

    time包中的Add和Sub的用法,Add用于计算某个时间之前和之后的时间点,Sub用于计算两个时间差 实例如下: package mainimport ("fmt""s ...

  8. golang格式化时间精确到毫秒

    如题,我们可能希望格式化时间精确到毫秒,可以这样做: start_time := time.Now() yyyyMMddHHmmss := start_time.Format("2006-0 ...

  9. golang获取时间所在周的起止时间

    1.分享一下翻译器的文件 type Transform struct {Value interface{}Time time.Time }var (timeLayoutMap = map[string ...

  10. Golang工具集-String工具,时间工具,http工具等

    gotool gotool是一个小而全的Golang工具集,主要是将日常开发中常用的到方法进行提炼集成,避免重复造轮子,提高工作效率,每一个方法都是作者经过工作经验,和从以往的项目中提炼出来的. 20 ...

最新文章

  1. c语言以空格分割字符串_C语言: 利用sscanf() 函数分割字符串
  2. 建立双链表(头插法)
  3. 聊聊kafka client chunkQueue 与 MaxLag值
  4. 在SAP中进行黏贴时必须要把之前的数据删掉后才能黏贴,不能直接使用黏贴来覆盖之前的数据,这个怎麼解?
  5. python全栈开发要学些什么_如何迅速学习Python 全栈开发?
  6. python爬虫之bs4库_三分钟搞定bs4库的解析器
  7. 已经被删除的PDF怎么用EasyRecovery恢复
  8. SpringBoot项目优雅的http客户端工具,太香了!
  9. 2021年全球及中国区块链投融资及技术专利情况:中国区块链相关注册企业达到9.36万余家,新增专利15985项 [图]
  10. Excel-散点图(相关性及数据分布)分析
  11. java邮件发送 qq与163邮箱互发和qq和163邮箱发送其他邮箱实例
  12. 瑞鹄转债上市价格预测
  13. 绘画系统——P5.js
  14. margin-left:-100%理解
  15. c# 扫描局域网IP列表的几种方法
  16. 编译报错:needed by ‘out/target/product/XXX.apk.....
  17. 电源电力专业术语整理
  18. 《中英双解》leetCode Arranging Coins (排列硬币)
  19. JDK1.8之Lambada表达式一
  20. 美团面试题:Hashmap的结构,1.7和1.8有哪些区别,史上最深入的分析

热门文章

  1. word2016标题序号变黑色竖线解决方法
  2. 虚拟机IP地址和主机名称配置
  3. 制造业考PMP是否有用?
  4. 百度站长平台“你无权访问该页面,点击确定按钮返回首页”
  5. SpringBoot+MyBatisPlus+Vue+ElementUI实现前后端分离的物业管理系统
  6. 量化投资学习-16:从波粒二象性和叠加原理看股票的三面:市场面、基本面、技术面
  7. 不动产租赁运营平台,为不动产租赁提供强劲的运营支持
  8. 斯蒂夫·乔布斯《你必须要找到你所爱的东西》
  9. Vuforia Vumark初探
  10. voip 网络电话快速搭建