解决XORM的时区问题

简介:

如果你升级使用了较为新版xorm(如v0.6.3)和go-sql-driver(如v1.3)的go类库,那么你就可能会遇到时区问题。 如

time.Parse("2006-01-02 15:04:05" ,"2018-01-15 12:11:12") // 2018-01-15T12:11:12+00:00

写入是数据库时候就会被改变为2018-01-15T20:11:12+00:00。 
上述的就是时区问题,因为我们使用的是东8时区,默认会被设置为0时区,解决方案很简单,只需要在main函数中或者main包中初始化时区:

time.LoadLocation("Asia/Shanghai")

数据库配置为

root:root@tcp(127.0.0.1:3306)/test?charset=utf8&interpolateParams=true

xorm的初始化修改为:

orm, err := initOrm(ds, maxIdleConn, maxOpenConn, debug)
if err != nil {
    return nil, err
}
r.Value = orm
orm.DatabaseTZ = time.Local // 必须
orm.TZLocation = time.Local // 必须
orm.SetMaxIdleConns(maxIdleConn)
orm.SetMaxOpenConns(maxOpenConn)

字符串转换时间也需要改为

time.ParseInLocation("2006-01-02 15:04:05" ,"2018-01-15 12:11:12",time.Local)

此时写库时区问题就可以得到解决了,但是读库问题如下的的方式:

rss, err := this.Repo.Query(ctx, sqlStr, pos, now, os)
images := make([]*models.ImageConf, 0, len(rss))

for _, rs := range rss {
    var tmpImage models.ImageConf
    MapToStruct(rs, &tmpImage)
    images = append(images, &tmpImage)
}

func MapToStruct(mapping map[string][]byte, j interface{}) {
    elem := reflect.ValueOf(j).Elem()
    for i := 0; i < elem.NumField(); i++ {
        var key string
        key = elem.Type().Field(i).Name
        switch elem.Field(i).Interface().(type) {
        case int, int8, int16, int32, int64:
            x, _ := strconv.ParseInt(string(mapping[key]), 10, 64)
            elem.Field(i).SetInt(x)
        case string:
            elem.Field(i).SetString(string(mapping[key]))
        case float64:
            x, _ := strconv.ParseFloat(string(mapping[key]), 64)
            elem.Field(i).SetFloat(x)
        case float32:
            x, _ := strconv.ParseFloat(string(mapping[key]), 32)
            elem.Field(i).SetFloat(x)
        case time.Time:
            timeStr := string(mapping[key])
            timeDB, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local)
            if err != nil {
                timeDB, err = time.ParseInLocation("2006-01-02", timeStr, time.Local)
                if err != nil {
                    timeDB, err = time.ParseInLocation("15:04:05", timeStr, time.Local)
                } else {
                    timeDB = time.Date(0, 0, 0, 0, 0, 0, 1, time.Local)
                }
            }
            elem.Field(i).Set(reflect.ValueOf(timeDB))
        }
    }
}

其中MapToStruct函数中的time.Time类型这儿有一个需要我们注意的,如果配置的数据库为

root:root@tcp(127.0.0.1:3306)/test?charset=utf8&interpolateParams=true&parseTime=true&loc=Local

多出了&parseTime=true&loc=Local此时timeStr := string(mapping[key])得到的将会是2006-01-02T15:04:05+08:00。 
那么你的转换格式应该为2006-01-02T15:04:05+08:00

总结一下:

  • 在项目中时区一定要在项目初始化时候就已经设置好
  • 字符串转换时间尽可能使用time.ParseInLocation
  • parseTime=true&loc=Local或者parseTime=true&loc=Asia%2FShanghaixorm解析时间类型为map[string][]byte有着影响
本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/2061278
相关文章
|
Shell Go
Go 语言入门很简单:Go 语言执行 Shell 命令(下)
Exec 是 os 包中的一个子包,它可用于使用 Go 运行外部命令。Go exec 命令教程展示了如何在 Golang 中执行 shell 命令和程序。
|
数据可视化
mac环境下graphviz安装及使用
mac环境下graphviz安装及使用
2459 0
mac环境下graphviz安装及使用
|
8月前
|
关系型数据库 MySQL
Mysql 蠕虫复制(查询的结果数据插入某个表中)
Mysql 蠕虫复制(查询的结果数据插入某个表中)
355 1
|
Go
【go 语言】PProf 的使用——协程(goroutine)和锁(mutex)分析(三)
【go 语言】PProf 的使用——协程(goroutine)和锁(mutex)分析(三)
1869 0
【go 语言】PProf 的使用——协程(goroutine)和锁(mutex)分析(三)
|
Kubernetes 负载均衡 网络协议
Kubernetes 跨集群流量调度实战
Kubernetes 问世于 2015 年,从一开始秉持着松耦合和可扩展的设计理念,也因此带来了 Kubernetes 生态的蓬勃发展。但这些大部分先限制在单一集群内,然后由于种种原因和目的企业内部创建的集群越来越多,比如单集群故障、监管要求、异地多机房可用区容灾、出于敏捷、降本考虑的混合云、多云部署、单一集群的承载能力受限、多版本 Kubernetes 集群共存等。多集群之后除了提升管理的难度外,首当其冲的就是多集群间的流量调度,这也是多集群部署的基础。没有跨集群的通信,多集群的收益也会大打折扣。
548 1
Kubernetes 跨集群流量调度实战
|
Ubuntu 开发工具
Ubuntu更换阿里云软件源
Ubuntu更换阿里云软件源
126383 0
Debian 官方源换为国内的源的操作方法
apt-get update 报错,采用更换源的方式解决问题。
36907 0
|
Linux 数据安全/隐私保护 Windows
更换(Pypi)pip源到国内镜像
pip国内的一些镜像 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.
211631 2
如何制作Win10启动U盘启动盘iso镜像文件
如何制作Win10启动U盘启动盘iso镜像文件
如何制作Win10启动U盘启动盘iso镜像文件
|
算法 Go 数据安全/隐私保护
golang中实现RSA(PKCS#1)加密解密
RSA非对称加密算法,基于PKCS#1规范, 我们在使用RSA的时候需要提供 公钥和私钥 , 我们可以通过openss来为我们生成对应的pem格式的公钥和私钥匙。 关于pkcs相关标准如下,摘自百度: PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封[22]。
3610 0