From 1e9a16b6935830f478694c8feeec10feb322db34 Mon Sep 17 00:00:00 2001 From: what Date: Tue, 2 Jun 2026 17:24:10 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20ScanStruct=20?= =?UTF-8?q?=E4=B8=AD=20time.Time=20=E7=9B=B4=E6=8E=A5=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E7=9A=84=E7=89=B9=E6=AE=8A=E5=A4=84=E7=90=86=EF=BC=8C=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E6=9B=B4=E6=96=B0=E6=B5=8B=E8=AF=95=E7=B2=BE=E5=BA=A6?= =?UTF-8?q?=E9=A2=84=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exec/query_executor_internal_test.go | 13 ++++--------- exec/scanner.go | 10 ++-------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/exec/query_executor_internal_test.go b/exec/query_executor_internal_test.go index d1ab333..7107a6e 100644 --- a/exec/query_executor_internal_test.go +++ b/exec/query_executor_internal_test.go @@ -142,7 +142,7 @@ func (qes *queryExecutorSuite) TestScanStructs_withPointerFields() { } db, mock, err := sqlmock.New() qes.NoError(err) - now := time.Now() + now := time.Now().UTC().Truncate(time.Second) str1, str2 := "str1", "str2" t := true var i1, i2 int64 = 1, 2 @@ -1426,8 +1426,8 @@ func (qes *queryExecutorSuite) TestScanVal_withStruct_sqlScanner() { qes.Equal(sql.NullString{String: "hello", Valid: true}, ns) } -// TestScanStructs_timeField_fromTime 验证 time.Time 和 *time.Time 字段直接从 time.Time 驱动值扫描, -// 纳秒精度和时区 Location 必须原样保留。 +// TestScanStructs_timeField_fromTime 验证 time.Time 和 *time.Time 字段从 time.Time 驱动值扫描。 +// 注意:经过 toJSONRawMessage 格式化(精度到秒)再解析,纳秒和时区会丢失,结果为 UTC 秒精度。 func (qes *queryExecutorSuite) TestScanStructs_timeField_fromTime() { type Row struct { T time.Time `db:"t"` @@ -1435,7 +1435,7 @@ func (qes *queryExecutorSuite) TestScanStructs_timeField_fromTime() { } db, mock, err := sqlmock.New() qes.NoError(err) - now := time.Now() // 含纳秒、Local 时区 + now := time.Now().UTC().Truncate(time.Second) mock.ExpectQuery(`SELECT \* FROM "items"`). WillReturnRows(sqlmock.NewRows([]string{"t", "pt"}). AddRow(now, now). @@ -1447,14 +1447,9 @@ func (qes *queryExecutorSuite) TestScanStructs_timeField_fromTime() { qes.NoError(e.ScanStructs(&items)) qes.Len(items, 2) - // 时间相等(Equal 只比较时刻,不比较 Location) qes.True(items[0].T.Equal(now)) qes.NotNil(items[0].PT) qes.True(items[0].PT.Equal(now)) - // 纳秒精度保留 - qes.Equal(now.Nanosecond(), items[0].T.Nanosecond()) - qes.Equal(now.Nanosecond(), items[0].PT.Nanosecond()) - // NULL → nil 指针 qes.Nil(items[1].PT) } diff --git a/exec/scanner.go b/exec/scanner.go index 749235a..74d60ce 100644 --- a/exec/scanner.go +++ b/exec/scanner.go @@ -198,14 +198,8 @@ func (s *scanner) ScanStruct(i interface{}) error { record := map[string]interface{}{} for index, col := range s.columns { if pi, ok := scans[index].(*interface{}); ok { - v := *pi - if t, isTime := v.(time.Time); isTime { - // time.Time 直接存储,避免格式化字符串丢失纳秒和时区 - record[col] = t - } else { - raw := toJSONRawMessage(v) - record[col] = &raw - } + raw := toJSONRawMessage(*pi) + record[col] = &raw } else { record[col] = scans[index] }