├── LICENSE ├── README.md ├── iso8601.go └── iso8601_test.go /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Joe Shaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iso8601 # 2 | 3 | iso8601 is a simple Go package for encoding `time.Time` in JSON in ISO 4 | 8601 format, without subsecond resolution or time zone info. 5 | 6 | ```go 7 | package main 8 | 9 | import ( 10 | "encoding/json" 11 | "fmt" 12 | "time" 13 | 14 | "github.com/joeshaw/iso8601" 15 | ) 16 | 17 | func main() { 18 | t := time.Now() 19 | 20 | // Standard JSON format 21 | // "2014-03-25T16:15:25.701623113-04:00" 22 | data, _ := json.Marshal(t) 23 | fmt.Println(string(data)) 24 | 25 | // ISO8601 JSON format 26 | // "2014-03-25T16:15:25" 27 | data, _ = json.Marshal(iso8601.Time(t)) 28 | fmt.Println(string(data)) 29 | 30 | // Output after decoding back to go. Note the loss of 31 | // precision and time zone info. 32 | // 2014-03-25 16:15:25 +0000 +0000 33 | var t2 iso8601.Time 34 | json.Unmarshal(data, &t2) 35 | fmt.Println(t2) 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /iso8601.go: -------------------------------------------------------------------------------- 1 | // The iso8601 package encodes and decodes time.Time in JSON in 2 | // ISO 8601 format, without subsecond resolution or time zone info. 3 | package iso8601 4 | 5 | import "time" 6 | 7 | const Format = "2006-01-02T15:04:05" 8 | const jsonFormat = `"` + Format + `"` 9 | 10 | var fixedZone = time.FixedZone("", 0) 11 | 12 | type Time time.Time 13 | 14 | // New constructs a new iso8601.Time instance from an existing 15 | // time.Time instance. This causes the nanosecond field to be set to 16 | // 0, and its time zone set to a fixed zone with no offset from UTC 17 | // (but it is *not* UTC itself). 18 | func New(t time.Time) Time { 19 | return Time(time.Date( 20 | t.Year(), 21 | t.Month(), 22 | t.Day(), 23 | t.Hour(), 24 | t.Minute(), 25 | t.Second(), 26 | 0, 27 | fixedZone, 28 | )) 29 | } 30 | 31 | func (it Time) MarshalJSON() ([]byte, error) { 32 | return []byte(time.Time(it).Format(jsonFormat)), nil 33 | } 34 | 35 | func (it *Time) UnmarshalJSON(data []byte) error { 36 | t, err := time.ParseInLocation(jsonFormat, string(data), fixedZone) 37 | if err == nil { 38 | *it = Time(t) 39 | } 40 | 41 | return err 42 | } 43 | 44 | func (it Time) String() string { 45 | return time.Time(it).String() 46 | } 47 | -------------------------------------------------------------------------------- /iso8601_test.go: -------------------------------------------------------------------------------- 1 | package iso8601 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestISO8601Time(t *testing.T) { 10 | now := New(time.Now().UTC()) 11 | 12 | data, err := json.Marshal(now) 13 | if err != nil { 14 | t.Fatal(err) 15 | } 16 | 17 | _, err = time.Parse(`"`+Format+`"`, string(data)) 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | 22 | var now2 Time 23 | err = json.Unmarshal(data, &now2) 24 | if err != nil { 25 | t.Fatal(err) 26 | } 27 | 28 | if now != now2 { 29 | t.Fatalf("Time %s does not equal expected %s", now2, now) 30 | } 31 | 32 | if now.String() != now2.String() { 33 | t.Fatalf("String format for %s does not equal expected %s", now2, now) 34 | } 35 | } 36 | --------------------------------------------------------------------------------