一般情况是后端将数据插入数据库,但是数据库的时区默认是1970 1月1日00:00:00 GMT(0时区时间也可称为标准时间),然后中国所处的是在东八区对比入UTC(世界协调时间)或者GMT(格林威治标准时间)就应该是 GMT +08:00,东八区就会对应加上8小时。
比如:插入一个时间段为:2019-06-06 18:10 到数据库中,你会看到数据库对应位置显示的缺是 :2019-06-06 10:10。然后你把这个时间查出来直接丢给前端,由前端自己本地化时区转化为用户所在时区对应的时间即可;
zoneOffset = new Date().getTimezoneOffset() * (- 60) // 东北区 => GMT + 08:00 => 28800秒
前端只需要传入这个方法调用的类型为Int的变量值即可:东八区对应该值为 28800 。
2. golang后端实现time包功能调用:
const TIME_LAYOUT = "2006-01-02 15:04:05"
func parseWithLocation(name string, timeStr string) (time.Time, error) {
locationName := name
if l, err := time.LoadLocation(locationName); err != nil {
println(err.Error())
return time.Time{}, err
} else {
lt, _ := time.ParseInLocation(TIME_LAYOUT, timeStr, l)
fmt.Println(locationName, lt)
return lt, nil
func testTime() {
fmt.Println("0. now: ", time.Now())
str := "2018-09-10 00:00:00"
fmt.Println("1. str: ", str)
t, _ := time.Parse(TIME_LAYOUT, str)
fmt.Println("2. Parse time: ", t)
tStr := t.Format(TIME_LAYOUT)
fmt.Println("3. Format time str: ", tStr)
name, offset := t.Zone()
name2, offset2 := t.Local().Zone()
fmt.Printf("4. Zone name: %v, Zone offset: %v\n", name, offset)
fmt.Printf("5. Local Zone name: %v, Local Zone offset: %v\n", name2, offset2)
tLocal := t.Local()
tUTC := t.UTC()
fmt.Printf("6. t: %v, Local: %v, UTC: %v\n", t, tLocal, tUTC)
fmt.Printf("7. t: %v, Local: %v, UTC: %v\n", t.Format(TIME_LAYOUT), tLocal.Format(TIME_LAYOUT), tUTC.Format(TIME_LAYOUT))
fmt.Printf("8. Local.Unix: %v, UTC.Unix: %v\n", tLocal.Unix(), tUTC.Unix())
str2 := "1969-12-31 23:59:59"
t2, _ := time.Parse(TIME_LAYOUT, str2)
fmt.Printf("9. str2:%v,time: %v, Unix: %v\n", str2, t2, t2.Unix())
fmt.Printf("10. %v, %v\n", tLocal.Format(time.ANSIC), tUTC.Format(time.ANSIC))
fmt.Printf("11. %v, %v\n", tLocal.Format(time.RFC822), tUTC.Format(time.RFC822))
fmt.Printf("12. %v, %v\n", tLocal.Format(time.RFC822Z), tUTC.Format(time.RFC822Z))
//指定时区
parseWithLocation("America/Cordoba", str)
parseWithLocation("Asia/Shanghai", str)
parseWithLocation("Asia/Beijing", str)
testTime()
输出如下:
0. now: 2018-09-19 19:06:07.3642781 +0800 CST m=+0.005995601
1. str: 2018-09-10 00:00:00
2. Parse time: 2018-09-10 00:00:00 +0000 UTC
3. Format time str: 2018-09-10 00:00:00
4. Zone name: UTC, Zone offset: 0
5. Local Zone name: CST, Local Zone offset: 28800
6. t: 2018-09-10 00:00:00 +0000 UTC, Local: 2018-09-10 08:00:00 +0800 CST, UTC: 2018-09-10 00:00:00 +0000 UTC
7. t: 2018-09-10 00:00:00, Local: 2018-09-10 08:00:00, UTC: 2018-09-10 00:00:00
8. Local.Unix: 1536537600, UTC.Unix: 1536537600
9. str2:1969-12-31 23:59:59,time: 1969-12-31 23:59:59 +0000 UTC, Unix: -1
10. Mon Sep 10 08:00:00 2018, Mon Sep 10 00:00:00 2018
11. 10 Sep 18 08:00 CST, 10 Sep 18 00:00 UTC
12. 10 Sep 18 08:00 +0800, 10 Sep 18 00:00 +0000
America/Cordoba 2018-09-10 00:00:00 -0300 -03
Asia/Shanghai 2018-09-10 00:00:00 +0800 CST
cannot find Asia/Beijing in zip file C:\Go\/lib/time/zoneinfo.zip
time.Now 得到的当前时间的时区跟电脑的当前时区一样。
time.Parse 把时间字符串转换为Time,时区是UTC时区。
不管Time变量存储的是什么时区,其Unix()方法返回的都是距离UTC时间:1970年1月1日0点0分0秒的秒数。
Unix()返回的秒数可以是负数,如果时间小于1970-01-01 00:00:00的话。
Zone方法可以获得变量的时区和时区与UTC的偏移秒数,应该支持夏令时和冬令时。
time.LoadLocation可以根据时区名创建时区Location,所有的时区名字可以在$GOROOT/lib/time/zoneinfo.zip文件中找到,解压zoneinfo.zip可以得到一堆目录和文件,我们只需要目录和文件的名字,时区名是目录名+文件名,比如”Asia/Shanghai”。中国时区名只有”Asia/Shanghai”和”Asia/Chongqing”,而没有”Asia/Beijing”。
time.ParseInLocation可以根据时间字符串和指定时区转换Time。
感谢中国只有一个时区而且没有夏令时和冬令时,可怕的美国居然有6个时区,想想都可怕。
进入正题:
GoLang time包默认是UTC ,可以通过下面两种方式设置时区
l,_ := time.LoadLocation("Asia/Shanghai")
fmt.Println(time.Now().In(l))
l,_ = time.LoadLocation("America/Adak")
fmt.Println(time.Now().In(l))
package main
import (
"fmt"
"time"
func main(){
var cstZone = time.FixedZone("GMT", 8*3600) // 东八
fmt.Println(time.Now().In(cstZone).Format("01-02-2006 15:04:05"))
LoadLocation 有个问题,它依赖于 IANA Time Zone Database (简称 tzdata 吧) 这个数据库,一般linux系统都带了,但是windows系统就没带。
没有 tzdata 就会从$GOROOT/中找。对于没有安装go环境的windows系统来说,就没办法通过 LoadLocation 设置时区。
但是也有办法,我们可以自己把tzdata文件放到自己的程序目录中,然后让 time 包能够从我们自己的程序目录中加载时区文件就可以了。
文件目录可以通过环境变量设置,在main方法中:
os.Setenv("ZONEINFO", '/home/tz/data.zip')
然后再调用 LoadLocation 方法就可以了。
推荐直接使用方法二即可!
cstZone := time.FixedZone("GMT", int(zoneOffset))
nowTimePare := timePare.In(cstZone).Format("2006-01-02 15:04:05")
if nowTimePare == "0001-01-01 08:00:00" {
return