@@ -46,7 +46,7 @@ func (ts *Timestamp) Scan(src any) error {
46
46
47
47
switch src := src .(type ) {
48
48
case string :
49
- return scanPlanTextTimestampToTimestampScanner {}.Scan ([]byte (src ), ts )
49
+ return ( & scanPlanTextTimestampToTimestampScanner {}) .Scan ([]byte (src ), ts )
50
50
case time.Time :
51
51
* ts = Timestamp {Time : src , Valid : true }
52
52
return nil
@@ -116,17 +116,21 @@ func (ts *Timestamp) UnmarshalJSON(b []byte) error {
116
116
return nil
117
117
}
118
118
119
- type TimestampCodec struct {}
119
+ type TimestampCodec struct {
120
+ // ScanLocation is the location that the time is assumed to be in for scanning. This is different from
121
+ // TimestamptzCodec.ScanLocation in that this setting does change the instant in time that the timestamp represents.
122
+ ScanLocation * time.Location
123
+ }
120
124
121
- func (TimestampCodec ) FormatSupported (format int16 ) bool {
125
+ func (* TimestampCodec ) FormatSupported (format int16 ) bool {
122
126
return format == TextFormatCode || format == BinaryFormatCode
123
127
}
124
128
125
- func (TimestampCodec ) PreferredFormat () int16 {
129
+ func (* TimestampCodec ) PreferredFormat () int16 {
126
130
return BinaryFormatCode
127
131
}
128
132
129
- func (TimestampCodec ) PlanEncode (m * Map , oid uint32 , format int16 , value any ) EncodePlan {
133
+ func (* TimestampCodec ) PlanEncode (m * Map , oid uint32 , format int16 , value any ) EncodePlan {
130
134
if _ , ok := value .(TimestampValuer ); ! ok {
131
135
return nil
132
136
}
@@ -220,27 +224,27 @@ func discardTimeZone(t time.Time) time.Time {
220
224
return t
221
225
}
222
226
223
- func (TimestampCodec ) PlanScan (m * Map , oid uint32 , format int16 , target any ) ScanPlan {
227
+ func (c * TimestampCodec ) PlanScan (m * Map , oid uint32 , format int16 , target any ) ScanPlan {
224
228
225
229
switch format {
226
230
case BinaryFormatCode :
227
231
switch target .(type ) {
228
232
case TimestampScanner :
229
- return scanPlanBinaryTimestampToTimestampScanner {}
233
+ return & scanPlanBinaryTimestampToTimestampScanner {location : c . ScanLocation }
230
234
}
231
235
case TextFormatCode :
232
236
switch target .(type ) {
233
237
case TimestampScanner :
234
- return scanPlanTextTimestampToTimestampScanner {}
238
+ return & scanPlanTextTimestampToTimestampScanner {location : c . ScanLocation }
235
239
}
236
240
}
237
241
238
242
return nil
239
243
}
240
244
241
- type scanPlanBinaryTimestampToTimestampScanner struct {}
245
+ type scanPlanBinaryTimestampToTimestampScanner struct { location * time. Location }
242
246
243
- func (scanPlanBinaryTimestampToTimestampScanner ) Scan (src []byte , dst any ) error {
247
+ func (plan * scanPlanBinaryTimestampToTimestampScanner ) Scan (src []byte , dst any ) error {
244
248
scanner := (dst ).(TimestampScanner )
245
249
246
250
if src == nil {
@@ -264,15 +268,18 @@ func (scanPlanBinaryTimestampToTimestampScanner) Scan(src []byte, dst any) error
264
268
microsecFromUnixEpochToY2K / 1000000 + microsecSinceY2K / 1000000 ,
265
269
(microsecFromUnixEpochToY2K % 1000000 * 1000 )+ (microsecSinceY2K % 1000000 * 1000 ),
266
270
).UTC ()
271
+ if plan .location != nil {
272
+ tim = time .Date (tim .Year (), tim .Month (), tim .Day (), tim .Hour (), tim .Minute (), tim .Second (), tim .Nanosecond (), plan .location )
273
+ }
267
274
ts = Timestamp {Time : tim , Valid : true }
268
275
}
269
276
270
277
return scanner .ScanTimestamp (ts )
271
278
}
272
279
273
- type scanPlanTextTimestampToTimestampScanner struct {}
280
+ type scanPlanTextTimestampToTimestampScanner struct { location * time. Location }
274
281
275
- func (scanPlanTextTimestampToTimestampScanner ) Scan (src []byte , dst any ) error {
282
+ func (plan * scanPlanTextTimestampToTimestampScanner ) Scan (src []byte , dst any ) error {
276
283
scanner := (dst ).(TimestampScanner )
277
284
278
285
if src == nil {
@@ -302,13 +309,17 @@ func (scanPlanTextTimestampToTimestampScanner) Scan(src []byte, dst any) error {
302
309
tim = time .Date (year , tim .Month (), tim .Day (), tim .Hour (), tim .Minute (), tim .Second (), tim .Nanosecond (), tim .Location ())
303
310
}
304
311
312
+ if plan .location != nil {
313
+ tim = time .Date (tim .Year (), tim .Month (), tim .Day (), tim .Hour (), tim .Minute (), tim .Second (), tim .Nanosecond (), plan .location )
314
+ }
315
+
305
316
ts = Timestamp {Time : tim , Valid : true }
306
317
}
307
318
308
319
return scanner .ScanTimestamp (ts )
309
320
}
310
321
311
- func (c TimestampCodec ) DecodeDatabaseSQLValue (m * Map , oid uint32 , format int16 , src []byte ) (driver.Value , error ) {
322
+ func (c * TimestampCodec ) DecodeDatabaseSQLValue (m * Map , oid uint32 , format int16 , src []byte ) (driver.Value , error ) {
312
323
if src == nil {
313
324
return nil , nil
314
325
}
@@ -326,7 +337,7 @@ func (c TimestampCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16,
326
337
return ts .Time , nil
327
338
}
328
339
329
- func (c TimestampCodec ) DecodeValue (m * Map , oid uint32 , format int16 , src []byte ) (any , error ) {
340
+ func (c * TimestampCodec ) DecodeValue (m * Map , oid uint32 , format int16 , src []byte ) (any , error ) {
330
341
if src == nil {
331
342
return nil , nil
332
343
}
0 commit comments