【问题标题】:Date conversion code behaving different on different machines日期转换代码在不同机器上表现不同
【发布时间】:2021-02-07 05:10:54
【问题描述】:

我有以下代码:

package main

import (
    "fmt"
    "time"
)

func main() {
    loc := "Jan 06"
    date := "2020-12-31 16:00:00 +0000 UTC"
    layout := "2006-01-02 15:04:05 -0700 MST"
    t, err := time.Parse(layout, date)
    if err != nil {
        fmt.Print("Error")
    }

    fmt.Println(t)
    GetFormattedDate(t, loc)
}

func GetFormattedDate(date time.Time, layout string) (string, error) {
    
    fmt.Println("\n\n====================================================")
    fmt.Println("time.Now(): ", time.Now())
    fmt.Println("time.Now().Location(): ", time.Now().Location())
    fmt.Println("Converting: ", date)
    configLocale := "Singapore"
    fmt.Println("configLocale: ", configLocale)

    loc, err := time.LoadLocation(configLocale)
    fmt.Println("loc: ", loc)
    if err != nil {
        return "", err
    }

    date = date.In(loc)
    fmt.Println("date.In(loc): ", date)
    fmt.Println("layout: ", layout)
    converted := fmt.Sprintf(date.Format(layout))
    fmt.Println("converted fmt: ", converted)
    fmt.Println("\n\n==================================================")
    return fmt.Sprintf(date.Format(layout)), nil
}

当我在本地运行它时,我得到:

====================================================
time.Now():  2009-11-10 23:00:00 +0000 UTC m=+0.000000001
time.Now().Location():  Local
Converting:  2020-12-31 16:00:00 +0000 UTC
configLocale:  Singapore
loc:  Singapore
date.In(loc):  2021-01-01 00:00:00 +0800 +08 // This is the issue
layout:  Jan 06
converted fmt:  Jan 21


==================================================

但是当我在我的 linux box 服务器上运行相同的代码时,我得到:

time.Now(): 2020-10-24 09:04:22.256288497 +0000 UTC m=+252.011109438
time.Now().Location(): UTC
Converting: 2020-12-31 16:00:00 +0000 UTC
msg":"configLocale: Singapore
msg":"loc: Singapore
date.In(loc): 2020-12-31 16:00:00 +0000 +0000 // This is the issue
layout: Jan 06
converted fmt: Dec 20

我想做什么:

我正在尝试将:2020-12-31 16:00:00 +0000 UTC 转换为区域设置特定日期,区域设置为 Singapore。我的布局是Jan 06

对于一台机器,此日期转换为Dec 20,对于另一台机器,它转换为Jan 21

特别是当我深入挖掘时,我觉得 date = date.In(loc) 方法在不同的机器上返回不同的结果,尽管将位置设置为 Singapore 并明确传递它,这在日志中很明显。

Playground

但是在服务器命令行上:

/ # zdump Singapore 
Singapore  Mon Oct 26 02:10:18 2020 +08

有什么建议可以解决这个问题吗?

【问题讨论】:

  • 这些机器似乎有不同的时区数据。修复它们。
  • @Volker 我没有完全掌握您提出的解决方案。
  • 我认为时区数据(用于将“新加坡”之类的字符串转换为对 UTC 的偏移量的数据。您的本地服务器认为新加坡是 UTC+8,您的 linux 服务器认为新加坡是 UTC +0。一个或两个都错了。你的 ZONEINFO 是什么?
  • 确保您服务器上的 tzdata 包(或类似的;详细信息取决于发行版)是最新的。
  • 谢谢各位,我会与 devops 团队核对这些信息,看看哪里不匹配。

标签: linux docker date go


【解决方案1】:

它是configLocale 的值。它必须是IANA Time Zone、“”、“UTC”或“Local”。 “新加坡”在列表中,但它是极少数不遵循Continent/Region 标准格式的国家之一。这是一种不寻常的格式,因此服务器机器上的查找失败,因此默认为 UTC(不返回错误,这可能是一个错误),并且由于新加坡提前 8 小时,您最终会延迟 8 小时。如果您将“亚洲/新加坡”用于 configLocale,它将起作用。

【讨论】:

  • 您好,我错过了提及我尝试了诸如 "Asia/Singapore" "Asia/Tokyo""Europe/Berlin" 之类的值,但所有这些都失败了。
  • 好吧,我仍然认为函数调用失败了,所以你可能会在其中放置一个断点或一些调试输出。
  • 是的,一件特别难的事情是在 docker 容器上进行远程调试,企业很少允许这样做。我正在追逐 devops 以允许这样做。谢谢!
  • 我也相信这绝对是一个环境问题。只是无法将我的手指放在它上面 - 还没有!
  • 好吧,您可以使用相同的 go 代码 time.LoadLocation,它调用 LoadLocationFromTZData,复制源代码 (golang.org/src/time/zoneinfo.go?s=15979:16028#L619),然后在测试程序中运行完全相同的代码。根据需要添加调试。
猜你喜欢
  • 2013-02-17
  • 2021-02-12
  • 2012-12-10
  • 2011-01-11
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多