在 Golang 中完全解析时间戳
Fully Parsing Timestamps in Golang
我正在尝试制作一个简单的工具来解析文件中 JSON 格式的行,并对数据库执行 INSERT
操作。
我有一个看起来像这样的结构:
type DataBlob struct {
....
Datetime time.Time `json:"datetime, string"`
....
}
解析代码如下:
scanner := bufio.NewScanner(file)
// Loop through all lines in the file
for scanner.Scan() {
var t DataBlob
// Decode the line, parse the JSON
dec := json.NewDecoder(strings.NewReader(scanner.Text()))
if err := dec.Decode(&t);
err != nil {
panic(err)
}
// Perform the database operation
executionString: = "INSERT INTO observations (datetime) VALUES ()"
_, err := db.Exec(executionString, t.Datetime)
if err != nil {
panic(err)
}
}
我的 JSON 文件有几行,每行包含一个 datetime
值,如下所示:
{ "datetime": 1465793854 }
当 datetime
被格式化为 Unix 时间戳时,Marshaller 抱怨:
panic: parsing time "1465793854" as ""2006-01-02T15:04:05Z07:00"": cannot parse "1465793854" as """
在生成 JSON 的脚本中(也是用 Golang 编写的),我尝试简单地打印 Time.time
类型的字符串表示形式,生成以下内容:
{ "datetime": "2016-06-13 00:23:34 -0400 EDT" }
当我去解析它时 Marshaller 抱怨说:
panic: parsing time ""2016-06-13 00:23:34 -0400 EDT"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 00:23:34 -0400 EDT"" as "T"
如果我也将此时间戳(看起来很标准)视为字符串并避免封送处理问题,当我尝试执行插入时 Postgres 会抱怨:
panic: pq: invalid input syntax for type timestamp: "2016-06-13 00:23:34 -0400 EDT"
这在很多层面上令人沮丧,但主要是因为如果我序列化一个 Time.time
类型,我认为它应该在过程的另一端仍然被理解。
我怎样才能解析这个时间戳来执行数据库插入?对于冗长的问题深表歉意,感谢您的帮助!
JSON 将 time.Time
expects 日期字符串解组为 RFC 3339 格式。
所以在生成 JSON 的 golang 程序中,不是简单地打印 time.Time
值,而是使用 Format 以 RFC 3339 格式打印它。
t.Format(time.RFC3339)
if I serialize a Time.time type, I would think it should still be
understood at the other side of the process
如果您将 Marshaller interface 与序列化一起使用,它确实会以 RFC 3339 格式输出日期。所以流程的另一方会理解它。所以你也可以这样做。
d := DataBlob{Datetime: t}
enc := json.NewEncoder(fileWriter)
enc.Encode(d)
作为参考,如果您需要使用时间类型进行自定义解组,则需要使用 UnmarshallJSON 方法创建您自己的类型。以时间戳为例
type Timestamp struct {
time.Time
}
// UnmarshalJSON decodes an int64 timestamp into a time.Time object
func (p *Timestamp) UnmarshalJSON(bytes []byte) error {
// 1. Decode the bytes into an int64
var raw int64
err := json.Unmarshal(bytes, &raw)
if err != nil {
fmt.Printf("error decoding timestamp: %s\n", err)
return err
}
// 2 - Parse the unix timestamp
*&p.Time = time.Unix(raw, 0)
return nil
}
然后在你的结构中使用类型:
type DataBlob struct {
....
Datetime Timestamp `json:"datetime"`
....
}
我正在尝试制作一个简单的工具来解析文件中 JSON 格式的行,并对数据库执行 INSERT
操作。
我有一个看起来像这样的结构:
type DataBlob struct {
....
Datetime time.Time `json:"datetime, string"`
....
}
解析代码如下:
scanner := bufio.NewScanner(file)
// Loop through all lines in the file
for scanner.Scan() {
var t DataBlob
// Decode the line, parse the JSON
dec := json.NewDecoder(strings.NewReader(scanner.Text()))
if err := dec.Decode(&t);
err != nil {
panic(err)
}
// Perform the database operation
executionString: = "INSERT INTO observations (datetime) VALUES ()"
_, err := db.Exec(executionString, t.Datetime)
if err != nil {
panic(err)
}
}
我的 JSON 文件有几行,每行包含一个 datetime
值,如下所示:
{ "datetime": 1465793854 }
当 datetime
被格式化为 Unix 时间戳时,Marshaller 抱怨:
panic: parsing time "1465793854" as ""2006-01-02T15:04:05Z07:00"": cannot parse "1465793854" as """
在生成 JSON 的脚本中(也是用 Golang 编写的),我尝试简单地打印 Time.time
类型的字符串表示形式,生成以下内容:
{ "datetime": "2016-06-13 00:23:34 -0400 EDT" }
当我去解析它时 Marshaller 抱怨说:
panic: parsing time ""2016-06-13 00:23:34 -0400 EDT"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 00:23:34 -0400 EDT"" as "T"
如果我也将此时间戳(看起来很标准)视为字符串并避免封送处理问题,当我尝试执行插入时 Postgres 会抱怨:
panic: pq: invalid input syntax for type timestamp: "2016-06-13 00:23:34 -0400 EDT"
这在很多层面上令人沮丧,但主要是因为如果我序列化一个 Time.time
类型,我认为它应该在过程的另一端仍然被理解。
我怎样才能解析这个时间戳来执行数据库插入?对于冗长的问题深表歉意,感谢您的帮助!
JSON 将 time.Time
expects 日期字符串解组为 RFC 3339 格式。
所以在生成 JSON 的 golang 程序中,不是简单地打印 time.Time
值,而是使用 Format 以 RFC 3339 格式打印它。
t.Format(time.RFC3339)
if I serialize a Time.time type, I would think it should still be understood at the other side of the process
如果您将 Marshaller interface 与序列化一起使用,它确实会以 RFC 3339 格式输出日期。所以流程的另一方会理解它。所以你也可以这样做。
d := DataBlob{Datetime: t}
enc := json.NewEncoder(fileWriter)
enc.Encode(d)
作为参考,如果您需要使用时间类型进行自定义解组,则需要使用 UnmarshallJSON 方法创建您自己的类型。以时间戳为例
type Timestamp struct {
time.Time
}
// UnmarshalJSON decodes an int64 timestamp into a time.Time object
func (p *Timestamp) UnmarshalJSON(bytes []byte) error {
// 1. Decode the bytes into an int64
var raw int64
err := json.Unmarshal(bytes, &raw)
if err != nil {
fmt.Printf("error decoding timestamp: %s\n", err)
return err
}
// 2 - Parse the unix timestamp
*&p.Time = time.Unix(raw, 0)
return nil
}
然后在你的结构中使用类型:
type DataBlob struct {
....
Datetime Timestamp `json:"datetime"`
....
}