Go语言的MySQL驱动没有正确地设置时间

8

我已经用golang开发了一个与mysql交互的微服务一段时间了,我很喜欢这门有才华的语言。但是我遇到了问题,不知道问题出现在我的代码中、mysql驱动程序中还是mysql本身。我的机器时区为UTC+3,我分享一些结果,希望能有所帮助。

//created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
mysql> select now();
"2016-11-07 22:43:02", //that is correct.

在Go中

fmt.PrintLn(time.Now().Local())
"2016-11-07 22:51:02" //that is correct too

但是当我将实体添加到数据库中时,MySQL Workbench显示的日期时间不正确。

"2016-11-07 19:51:02" // 

Go 代码:

func (this *AppLogHandler) addLog(_log *AppLog) (int64, error){
    fmt.Println("addLog")
    db:= this.Context.DB
    stmt, err := db.Prepare("INSERT tbl_logs SET user_id=?,ip_proxy=?, ip_original=?, end_point=?, http_method=?, message=?, status=?, created_date=?")
    if(err != nil){
        log.Println(err)
        return -1, err
    }
    defer stmt.Close()
    res, err := stmt.Exec(&_log.UserID, &_log.IPProxy, &_log.IPOriginal, &_log.Endpoint, &_log.HttpMethod, &_log.Message, &_log.Status, &_log.CreatedDate)
    if(err != nil){
        log.Println(err)
        return -1, err
    }
    return res.LastInsertId()
}

/// some code here
    app_log := AppLog{}
    app_log.IPProxy = r.RemoteAddr
    app_log.IPOriginal = r.Header.Get("X-Forwarded-For")
    app_log.CreatedDate = time.Now().Local()
    app_log.UserID = user_id
    app_log.Endpoint = r.URL.Path
    app_log.HttpMethod = r.Method
    fmt.Println(app_log.CreatedDate)
    return this.addLog(&app_log)

大家好,我需要你们的帮助。我已经花了几个小时都无法解决这个问题。

mysql=>  Ver 14.14 Distrib 5.7.15, for osx10.11 (x86_64) using  EditLine wrapper
go => 1.7
mysql driver => 1.2, https://github.com/go-sql-driver/mysql/

你是在同一台机器上运行吗?如果在不同的时区的机器上运行或者某个机器与其NTP服务器不同步,可能会得到不同的结果。 - Christian Grabowski
是的,在同一台机器上。 - RockOnGom
驱动程序可能将其作为字符串传递,然后解析为time.Time构造函数,这将将其转换为UTC。尽管time.Time#Local()返回一个time.Time。嗯。 - Christian Grabowski
可能那就是原因。 - RockOnGom
5
对UTC有何厌恶情绪?一般来说,UTC是最佳实践,因为它为您提供了一个真正的单一数据来源。 - Christian Grabowski
抱歉,你是正确的!谢谢。 - RockOnGom
1个回答

10

mysql 驱动有一个默认时区的配置参数,你可以将其设置为time.Local(默认值为time.UTC)。在保存值时,它会先将时间戳转换为UTC时区,然后将其发送到数据库。

正如评论中已经提到的那样,更加稳健的方法是接受默认的Loc,并在数据库中标准化使用UTC。这极大地简化了以后涉及日期计算的任何事情,并且如果只是在显示值时将其从UTC转换为本地时间,则不会对查看数据的人的时区进行假设。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接