1+ package models
2+
3+ import (
4+ "database/sql/driver"
5+ "encoding/json"
6+ "fmt"
7+ "time"
8+ )
9+
10+ // NullTime 兼容SQLite的可空时间类型
11+ type NullTime struct {
12+ Time time.Time
13+ Valid bool // Valid表示Time不是NULL
14+ }
15+
16+ // Scan 实现sql.Scanner接口
17+ func (nt * NullTime ) Scan (value interface {}) error {
18+ if value == nil {
19+ nt .Time , nt .Valid = time.Time {}, false
20+ return nil
21+ }
22+
23+ switch v := value .(type ) {
24+ case time.Time :
25+ nt .Time , nt .Valid = v , true
26+ return nil
27+ case string :
28+ if v == "" {
29+ nt .Time , nt .Valid = time.Time {}, false
30+ return nil
31+ }
32+ // 尝试多种时间格式
33+ formats := []string {
34+ time .RFC3339 ,
35+ time .RFC3339Nano ,
36+ "2006-01-02 15:04:05" ,
37+ "2006-01-02T15:04:05" ,
38+ "2006-01-02 15:04:05.000000" ,
39+ }
40+ for _ , format := range formats {
41+ if t , err := time .Parse (format , v ); err == nil {
42+ nt .Time , nt .Valid = t , true
43+ return nil
44+ }
45+ }
46+ return fmt .Errorf ("无法解析时间字符串: %s" , v )
47+ case []byte :
48+ return nt .Scan (string (v ))
49+ default :
50+ return fmt .Errorf ("无法将 %T 转换为 NullTime" , value )
51+ }
52+ }
53+
54+ // Value 实现driver.Valuer接口
55+ func (nt NullTime ) Value () (driver.Value , error ) {
56+ if ! nt .Valid {
57+ return nil , nil
58+ }
59+ return nt .Time .Format ("2006-01-02 15:04:05" ), nil
60+ }
61+
62+ // Ptr 返回指向时间的指针,如果无效则返回nil
63+ func (nt * NullTime ) Ptr () * time.Time {
64+ if ! nt .Valid {
65+ return nil
66+ }
67+ return & nt .Time
68+ }
69+
70+ // MarshalJSON 实现JSON序列化
71+ func (nt NullTime ) MarshalJSON () ([]byte , error ) {
72+ if ! nt .Valid {
73+ return []byte ("null" ), nil
74+ }
75+ return json .Marshal (nt .Time )
76+ }
77+
78+ // UnmarshalJSON 实现JSON反序列化
79+ func (nt * NullTime ) UnmarshalJSON (data []byte ) error {
80+ if string (data ) == "null" {
81+ nt .Valid = false
82+ return nil
83+ }
84+
85+ var t time.Time
86+ if err := json .Unmarshal (data , & t ); err != nil {
87+ return err
88+ }
89+
90+ nt .Time = t
91+ nt .Valid = true
92+ return nil
93+ }
0 commit comments