Macos Golang JSON时间默认布局因平台而异?

Macos Golang JSON时间默认布局因平台而异?,macos,ubuntu,go,Macos,Ubuntu,Go,我遇到了一个奇怪的问题,time.time的JSON编码字符串在我的开发环境(OSX)和生产环境(Ubuntu 14.04 x64)之间变化 OSX: Ubuntu 14.04 x64: { // RFC3339Nano layout created_at: "2015-05-21T15:00:46.546000003Z", } 我一直在谷歌上搜索。我想不出这个。以下是更多信息: 这是一个简单的web服务应用程序 在我的OSX机器上运行go 1.4.1 我在我的OSX机器上交叉编译应

我遇到了一个奇怪的问题,
time.time
的JSON编码字符串在我的开发环境(OSX)和生产环境(Ubuntu 14.04 x64)之间变化

OSX:

Ubuntu 14.04 x64:

{
  // RFC3339Nano layout
  created_at: "2015-05-21T15:00:46.546000003Z",
}
我一直在谷歌上搜索。我想不出这个。以下是更多信息:

  • 这是一个简单的web服务应用程序
  • 在我的OSX机器上运行
    go 1.4.1
  • 我在我的OSX机器上交叉编译应用程序以进行如下部署:
    • GOOS=linux-GOARCH=amd64 go-build

如果您有任何见解,我们将不胜感激

RFC3339没有提到时间的精确性。看起来Ubuntu坚持要再加上9位小数的精度,根据RFC3339,这很好

在iOS/MacOS X上,相同的日期格式解析器不能解析带小数点和不带小数点的秒,因此我使用两种格式

"yyyy'-'MM'-'dd'T'HH':'mm':'ssX5"
"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSSSSSSSX5"
两种都试试。(事实上,我有六个S字符,因为我认为任何理智的人都不会使用超过六个小数。这是错误的)


我认为iOS/macosx中的日期格式是由Unicode标准标准化的,因此这可能也适用于其他解析器。出于效率考虑,我会记住上次哪个解析器工作,然后首先尝试那个解析器——如果一个日期是纳秒,那么下一个日期也可能是纳秒

时间的来源是:

//MarshalJSON实现json.Marshaler接口。
//时间是RFC 3339格式的带引号的字符串,如果存在,则添加亚秒精度。
func(t时间)MarshalJSON()([]字节,错误){
如果y:=t.Year();y<0 | | y>=10000{
//RFC3339清楚地表明,年份正好是4位数字。
//更多讨论见golang.org/issue/4556#c15。
返回nil,errors.New(“Time.MarshalJSON:超出范围[09999]的年份”)
}
返回[]字节(t.Format(``+RFC3339Nano+``)),无
}
[]

在所有平台上都是一样的。 注:

[…]如果存在,则添加亚秒精度

而那
RFC3339Nano=“2006-01-02T15:04:05.9999999 Z07:00”
。 “9”的平均值最多使用那么多数字,但删除尾随的零。 因此,看起来您的两个示例都可以匹配此格式。 (当解析时间过去时,无论格式如何,始终接受并解析分数秒)

的第5.6节规定,分数秒是可选的,可以包括也可以不包括在内(只是说,如果小数点存在,则后面必须至少有一位数字)


出于某种原因,您在一个系统上使用的时间是否只有二次精度或类似精度?(例如,这是否来自某个文件系统或仅在其中一个操作系统上存储秒数的其他子系统?)

您给定的格式字符串不适用于Go(这就是这个问题的内容)。在Go格式字符串中,如果您希望小数点后正好有三位数字,则使用“05.000”;如果您希望最多有三位数字并删除尾随零,则使用“05.999”(当然,根据需要使用更少或更多的0或9)。在Go解析时,它将始终接受并解析小数秒。感谢@gnasher729的回复。你正确地推断出我正在使用iOS应用程序。我希望NSDateFormatter能更聪明一点。没有简单的方法来规范化从Go到整秒的日期,所以我将尝试一对像您建议的格式化程序谢谢!是的,我现在意识到这不是一个真正的问题。使用此功能的客户端必须能够同时使用这两种功能。我假设文件系统上存在一些差异。
{
  // RFC3339Nano layout
  created_at: "2015-05-21T15:00:46.546000003Z",
}
"yyyy'-'MM'-'dd'T'HH':'mm':'ssX5"
"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSSSSSSSX5"
// MarshalJSON implements the json.Marshaler interface.
// The time is a quoted string in RFC 3339 format, with sub-second precision added if present.
func (t Time) MarshalJSON() ([]byte, error) {
        if y := t.Year(); y < 0 || y >= 10000 {
                // RFC 3339 is clear that years are 4 digits exactly.
                // See golang.org/issue/4556#c15 for more discussion.
                return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
        }
        return []byte(t.Format(`"` + RFC3339Nano + `"`)), nil
}