github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/util/datetime/date_time.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2017 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 // Package datetime implements marshalling of Go DateTime values into Noms structs 23 // with type DateTimeType. 24 package datetime 25 26 import ( 27 "context" 28 "math" 29 "time" 30 31 "github.com/dolthub/dolt/go/store/marshal" 32 "github.com/dolthub/dolt/go/store/types" 33 ) 34 35 const ( 36 datetypename = "DateTime" 37 hrsEncodingName = "noms-datetime" 38 ) 39 40 // DateTime implements marshaling of time.Time to and from Noms. 41 type DateTime struct { 42 time.Time 43 } 44 45 // DateTimeType is the Noms type used to represent date time objects in Noms. 46 // The field secSinceEpoch may contain fractions in cases where seconds are 47 // not sufficient. 48 var DateTimeType, _ = types.MakeStructTypeFromFields(datetypename, types.FieldMap{ 49 "secSinceEpoch": types.PrimitiveTypeMap[types.FloatKind], 50 }) 51 52 var dateTimeTemplate = types.MakeStructTemplate(datetypename, []string{"secSinceEpoch"}) 53 54 // Epoch is the unix Epoch. This time is very consistent, 55 // which makes it useful for testing or checking for uninitialized values 56 var Epoch = DateTime{time.Unix(0, 0)} 57 58 func init() { 59 RegisterHRSCommenter(time.Local) 60 } 61 62 // Now is an alias for a DateTime initialized with time.Now() 63 func Now() DateTime { 64 return DateTime{time.Now()} 65 } 66 67 // MarshalNoms makes DateTime implement marshal.Marshaler and it makes 68 // DateTime marshal into a Noms struct with type DateTimeType. 69 func (dt DateTime) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 70 return dateTimeTemplate.NewStruct(vrw.Format(), []types.Value{types.Float(float64(dt.Unix()) + float64(dt.Nanosecond())*1e-9)}) 71 } 72 73 // MarshalNomsType makes DateTime implement marshal.TypeMarshaler and it 74 // allows marshal.MarshalType to work with DateTime. 75 func (dt DateTime) MarshalNomsType() (*types.Type, error) { 76 return DateTimeType, nil 77 } 78 79 // UnmarshalNoms makes DateTime implement marshal.Unmarshaler and it allows 80 // Noms struct with type DateTimeType able to be unmarshaled onto a DateTime 81 // Go struct 82 func (dt *DateTime) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 83 strct := struct { 84 SecSinceEpoch float64 85 }{} 86 err := marshal.Unmarshal(ctx, nbf, v, &strct) 87 if err != nil { 88 return err 89 } 90 91 s, frac := math.Modf(strct.SecSinceEpoch) 92 *dt = DateTime{time.Unix(int64(s), int64(frac*1e9))} 93 return nil 94 } 95 96 type DateTimeCommenter struct { 97 tz *time.Location 98 } 99 100 func (c DateTimeCommenter) Comment(ctx context.Context, v types.Value) string { 101 if s, ok := v.(types.Struct); ok { 102 if secsV, ok, err := s.MaybeGet("secSinceEpoch"); err != nil { 103 panic(err) 104 } else if ok { 105 if secsF, ok := secsV.(types.Float); ok { 106 s, frac := math.Modf(float64(secsF)) 107 dt := time.Unix(int64(s), int64(frac*1e9)) 108 return dt.In(c.tz).Format(time.RFC3339) 109 } 110 } 111 } 112 return "" 113 } 114 115 func RegisterHRSCommenter(tz *time.Location) { 116 hrsCommenter := DateTimeCommenter{tz: tz} 117 types.RegisterHRSCommenter(datetypename, hrsEncodingName, hrsCommenter) 118 }