github.com/ndau/noms@v1.0.5/go/util/datetime/date_time.go (about) 1 // Copyright 2017 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 // Package datetime implements marshalling of Go DateTime values into Noms structs 6 // with type DateTimeType. 7 package datetime 8 9 import ( 10 "math" 11 "time" 12 13 "github.com/ndau/noms/go/marshal" 14 "github.com/ndau/noms/go/types" 15 ) 16 17 const ( 18 datetypename = "DateTime" 19 hrsEncodingName = "noms-datetime" 20 ) 21 22 // DateTime implements marshaling of time.Time to and from Noms. 23 type DateTime struct { 24 time.Time 25 } 26 27 // DateTimeType is the Noms type used to represent date time objects in Noms. 28 // The field secSinceEpoch may contain fractions in cases where seconds are 29 // not sufficient. 30 var DateTimeType = types.MakeStructTypeFromFields(datetypename, types.FieldMap{ 31 "secSinceEpoch": types.NumberType, 32 }) 33 34 var dateTimeTemplate = types.MakeStructTemplate(datetypename, []string{"secSinceEpoch"}) 35 36 // Epoch is the unix Epoch. This time is very consistent, 37 // which makes it useful for testing or checking for uninitialized values 38 var Epoch = DateTime{time.Unix(0, 0)} 39 40 func init() { 41 RegisterHRSCommenter(time.Local) 42 } 43 44 // Now is an alias for a DateTime initialized with time.Now() 45 func Now() DateTime { 46 return DateTime{time.Now()} 47 } 48 49 // MarshalNoms makes DateTime implement marshal.Marshaler and it makes 50 // DateTime marshal into a Noms struct with type DateTimeType. 51 func (dt DateTime) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 52 return dateTimeTemplate.NewStruct([]types.Value{types.Number(float64(dt.Unix()) + float64(dt.Nanosecond())*1e-9)}), nil 53 } 54 55 // MarshalNomsType makes DateTime implement marshal.TypeMarshaler and it 56 // allows marshal.MarshalType to work with DateTime. 57 func (dt DateTime) MarshalNomsType() (*types.Type, error) { 58 return DateTimeType, nil 59 } 60 61 // UnmarshalNoms makes DateTime implement marshal.Unmarshaler and it allows 62 // Noms struct with type DateTimeType able to be unmarshaled onto a DateTime 63 // Go struct 64 func (dt *DateTime) UnmarshalNoms(v types.Value) error { 65 strct := struct { 66 SecSinceEpoch float64 67 }{} 68 err := marshal.Unmarshal(v, &strct) 69 if err != nil { 70 return err 71 } 72 73 s, frac := math.Modf(strct.SecSinceEpoch) 74 *dt = DateTime{time.Unix(int64(s), int64(frac*1e9))} 75 return nil 76 } 77 78 type DateTimeCommenter struct { 79 tz *time.Location 80 } 81 82 func (c DateTimeCommenter) Comment(v types.Value) string { 83 if !types.IsValueSubtypeOf(v, DateTimeType) { 84 return "" 85 } 86 var dt DateTime 87 marshal.MustUnmarshal(v, &dt) 88 return dt.In(c.tz).Format(time.RFC3339) 89 } 90 91 func RegisterHRSCommenter(tz *time.Location) { 92 hrsCommenter := DateTimeCommenter{tz: tz} 93 types.RegisterHRSCommenter(datetypename, hrsEncodingName, hrsCommenter) 94 }