mirror of https://github.com/perkeep/perkeep.git
types: make Time3339 work for Go 1 too
Fixes http://code.google.com/p/camlistore/issues/detail?id=109 Change-Id: I4c30a77465e7774a0a867e95767f3e0ef1be7ec6
This commit is contained in:
parent
981a4c9fbd
commit
76d6a101b2
|
@ -19,9 +19,18 @@ package types
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
goVersion = runtime.Version()
|
||||
isGo10 = goVersion == "go1" || strings.HasPrefix(runtime.Version(), "go1.0")
|
||||
dotNumbers = regexp.MustCompile(`\.\d+`)
|
||||
)
|
||||
|
||||
// Time3339 is a time.Time which encodes to and from JSON
|
||||
// as an RFC 3339 time in UTC.
|
||||
type Time3339 time.Time
|
||||
|
@ -39,10 +48,38 @@ func (t Time3339) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal(t.String())
|
||||
}
|
||||
|
||||
func parseForGo10(s string) (time.Time, error) {
|
||||
var numbers string
|
||||
noNanos := dotNumbers.ReplaceAllStringFunc(s, func(m string) string {
|
||||
numbers = m
|
||||
return ""
|
||||
})
|
||||
t, err := time.Parse(time.RFC3339, noNanos)
|
||||
if err != nil {
|
||||
return t, fmt.Errorf("Failed to parse %q as an RFC 3339 time: %v", noNanos, err)
|
||||
}
|
||||
if numbers != "" {
|
||||
nanos, err := time.ParseDuration(numbers + "s")
|
||||
if err != nil {
|
||||
return t, fmt.Errorf("Failed to parse %q as a duration: %v", numbers+"s", err)
|
||||
}
|
||||
t = t.Add(nanos)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *Time3339) UnmarshalJSON(b []byte) error {
|
||||
if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
|
||||
return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time")
|
||||
}
|
||||
if isGo10 {
|
||||
tgo10, err := parseForGo10(string(b[1 : len(b)-1]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = Time3339(tgo10)
|
||||
return nil
|
||||
}
|
||||
tm, err := time.Parse(time.RFC3339Nano, string(b[1:len(b)-1]))
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -55,12 +55,17 @@ func TestTime3339_empty(t *testing.T) {
|
|||
// {enc: "0000-00-00T00:00:00Z"}, Go bug files
|
||||
{enc: "1970-01-01T00:00:00Z", z: true},
|
||||
{enc: "2001-02-03T04:05:06Z", z: false},
|
||||
{enc: "2001-02-03T04:05:06+06:00", z: false},
|
||||
{enc: "2001-02-03T04:05:06-06:00", z: false},
|
||||
{enc: "2001-02-03T04:05:06.123456789Z", z: false},
|
||||
{enc: "2001-02-03T04:05:06.123456789+06:00", z: false},
|
||||
{enc: "2001-02-03T04:05:06.123456789-06:00", z: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var tm Time3339
|
||||
err := json.Unmarshal([]byte("\"" + tt.enc + "\""), &tm)
|
||||
err := json.Unmarshal([]byte("\""+tt.enc+"\""), &tm)
|
||||
if tm.IsZero() != tt.z {
|
||||
t.Logf("unmarshal %q = %v (%d), %v; zero=%v; want %v", tt.enc, tm.Time(), tm.Time().Unix(), err,
|
||||
t.Errorf("unmarshal %q = %v (%d), %v; zero=%v; want %v", tt.enc, tm.Time(), tm.Time().Unix(), err,
|
||||
!tt.z, tt.z)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue