私はGoを学んでいて、日時のJSONアンマーシャリングを実行しようとしています。
Cで作成したプログラムによって生成されたJSONがあり、有効だと思ったものを出力しています ISO8601 / RFC3339 タイムゾーンオフセット。次の形式の文字列で strftime
を使用しています。
%Y-%m-%dT%H:%M:%S.%f%z
(%f
は strftime
でサポートされていないことに注意してください。ネイティブでは、ナノ秒に置き換えるラッパーがあります)。
これにより、次の結果が生成されます。
2016-08-08T21:35:14.052975+0200
ただし、Goでこれをアンマーシャリングしても機能しません: https://play.golang.org/p/vzOXbzAwdW
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse(time.RFC3339Nano, "2016-08-08T21:35:14.052975+0200")
if err != nil {
panic(err)
}
fmt.Println(t)
}
出力:
panic: parsing time "2016-08-08T21:35:14.052975+0200" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "+0200" as "Z07:00"
(実例: https://play.golang.org/p/5xcM0aHsSw )
これは、 RFC3339は、タイムゾーンオフセットが02:00
で:
の形式であると想定しているためですが、 strftime
は次のように出力します。 0200
。
したがって、正しい形式を出力するには、Cプログラムでこれを修正する必要があります。
%z The +hhmm or -hhmm numeric timezone (that is, the hour and
minute offset from UTC). (SU)
ただし、現在、この誤った形式のJSONファイルがたくさんあります。
2016-08-08T21:35:14.052975+0200
正しい代わりに(タイムゾーンオフセットに:
を使用):
2016-08-08T21:35:14.052975+02:00
それでも、Goプログラムで正しくアンマーシャリングできるようにしたいです。できれば、この違いだけを持つ2つの異なるJSONファイルをまったく同じ方法で解析する必要があります。
JSONへのマーシャリングに関しては、正しい形式を使用する必要があります。
これが私のstruct
で定義した方法です。
Time time.Time `json:"time"`
だから問題は、これを行う「Go」の方法は何ですか?
また、私のコード例では、RFC3339Nano
を使用しています。構造体のメタデータでもそれをどのように指定しますか? json:"time"
だけで今持っているので、ナノ秒は無視されますか?
両方の形式をサポートする独自のtime
フィールドタイプを定義できます。
type MyTime struct {
time.Time
}
func (self *MyTime) UnmarshalJSON(b []byte) (err error) {
s := string(b)
// Get rid of the quotes "" around the value.
// A second option would be to include them
// in the date format string instead, like so below:
// time.Parse(`"`+time.RFC3339Nano+`"`, s)
s = s[1:len(s)-1]
t, err := time.Parse(time.RFC3339Nano, s)
if err != nil {
t, err = time.Parse("2006-01-02T15:04:05.999999999Z0700", s)
}
self.Time = t
return
}
type Test struct {
Time MyTime `json:"time"`
}
上記の例では、次のように定義された事前定義された形式time.RFC3339Nano
を使用します。
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
:
を削除します
"2006-01-02T15:04:05.999999999Z0700"
time.Parse
で使用されるこの時間形式については、次のように説明します。 https://golang.org/pkg/time/#pkg-constants
time.Parse
https://golang.org/pkg/time/#Parse のドキュメントも参照してください。
P.S.年2006
が時間形式の文字列で使用されているのは、おそらくその年にGolangの最初のバージョンがリリースされたためです。