github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go (about) 1 // Copyright (C) MongoDB, Inc. 2017-present. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7 package bsoncodec 8 9 import ( 10 "fmt" 11 "reflect" 12 "time" 13 14 "go.mongodb.org/mongo-driver/bson/bsonoptions" 15 "go.mongodb.org/mongo-driver/bson/bsonrw" 16 "go.mongodb.org/mongo-driver/bson/bsontype" 17 "go.mongodb.org/mongo-driver/bson/primitive" 18 ) 19 20 const ( 21 timeFormatString = "2006-01-02T15:04:05.999Z07:00" 22 ) 23 24 // TimeCodec is the Codec used for time.Time values. 25 // 26 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with the 27 // TimeCodec registered. 28 type TimeCodec struct { 29 // UseLocalTimeZone specifies if we should decode into the local time zone. Defaults to false. 30 // 31 // Deprecated: Use bson.Decoder.UseLocalTimeZone instead. 32 UseLocalTimeZone bool 33 } 34 35 var ( 36 defaultTimeCodec = NewTimeCodec() 37 38 // Assert that defaultTimeCodec satisfies the typeDecoder interface, which allows it to be used 39 // by collection type decoders (e.g. map, slice, etc) to set individual values in a collection. 40 _ typeDecoder = defaultTimeCodec 41 ) 42 43 // NewTimeCodec returns a TimeCodec with options opts. 44 // 45 // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with the 46 // TimeCodec registered. 47 func NewTimeCodec(opts ...*bsonoptions.TimeCodecOptions) *TimeCodec { 48 timeOpt := bsonoptions.MergeTimeCodecOptions(opts...) 49 50 codec := TimeCodec{} 51 if timeOpt.UseLocalTimeZone != nil { 52 codec.UseLocalTimeZone = *timeOpt.UseLocalTimeZone 53 } 54 return &codec 55 } 56 57 func (tc *TimeCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { 58 if t != tTime { 59 return emptyValue, ValueDecoderError{ 60 Name: "TimeDecodeValue", 61 Types: []reflect.Type{tTime}, 62 Received: reflect.Zero(t), 63 } 64 } 65 66 var timeVal time.Time 67 switch vrType := vr.Type(); vrType { 68 case bsontype.DateTime: 69 dt, err := vr.ReadDateTime() 70 if err != nil { 71 return emptyValue, err 72 } 73 timeVal = time.Unix(dt/1000, dt%1000*1000000) 74 case bsontype.String: 75 // assume strings are in the isoTimeFormat 76 timeStr, err := vr.ReadString() 77 if err != nil { 78 return emptyValue, err 79 } 80 timeVal, err = time.Parse(timeFormatString, timeStr) 81 if err != nil { 82 return emptyValue, err 83 } 84 case bsontype.Int64: 85 i64, err := vr.ReadInt64() 86 if err != nil { 87 return emptyValue, err 88 } 89 timeVal = time.Unix(i64/1000, i64%1000*1000000) 90 case bsontype.Timestamp: 91 t, _, err := vr.ReadTimestamp() 92 if err != nil { 93 return emptyValue, err 94 } 95 timeVal = time.Unix(int64(t), 0) 96 case bsontype.Null: 97 if err := vr.ReadNull(); err != nil { 98 return emptyValue, err 99 } 100 case bsontype.Undefined: 101 if err := vr.ReadUndefined(); err != nil { 102 return emptyValue, err 103 } 104 default: 105 return emptyValue, fmt.Errorf("cannot decode %v into a time.Time", vrType) 106 } 107 108 if !tc.UseLocalTimeZone && !dc.useLocalTimeZone { 109 timeVal = timeVal.UTC() 110 } 111 return reflect.ValueOf(timeVal), nil 112 } 113 114 // DecodeValue is the ValueDecoderFunc for time.Time. 115 func (tc *TimeCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { 116 if !val.CanSet() || val.Type() != tTime { 117 return ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: val} 118 } 119 120 elem, err := tc.decodeType(dc, vr, tTime) 121 if err != nil { 122 return err 123 } 124 125 val.Set(elem) 126 return nil 127 } 128 129 // EncodeValue is the ValueEncoderFunc for time.TIme. 130 func (tc *TimeCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { 131 if !val.IsValid() || val.Type() != tTime { 132 return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} 133 } 134 tt := val.Interface().(time.Time) 135 dt := primitive.NewDateTimeFromTime(tt) 136 return vw.WriteDateTime(int64(dt)) 137 }