Skip to content
This repository was archived by the owner on Jun 10, 2025. It is now read-only.

Commit c1b91e8

Browse files
Add
1 parent e757531 commit c1b91e8

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

model/time.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package model
2+
3+
import (
4+
"database/sql/driver"
5+
"fmt"
6+
"time"
7+
)
8+
9+
// rfc3339Milli is like time.RFC3339Nano, but with millisecond precision, and fractional seconds do not have trailing
10+
// zeros removed.
11+
const rfc3339Milli = "2006-01-02T15:04:05.000Z07:00"
12+
13+
type Time struct {
14+
T time.Time
15+
}
16+
17+
func (t *Time) String() string {
18+
if t == nil {
19+
return ""
20+
}
21+
return t.T.UTC().Format(rfc3339Milli)
22+
}
23+
24+
func ParseTime(v string) (Time, error) {
25+
t, err := time.Parse(rfc3339Milli, v)
26+
if err != nil {
27+
return Time{}, err
28+
}
29+
return Time{T: t}, nil
30+
}
31+
32+
// Value satisfies driver.Valuer interface.
33+
func (t Time) Value() (driver.Value, error) {
34+
return t.T.UTC().Format(rfc3339Milli), nil
35+
}
36+
37+
// Scan satisfies sql.Scanner interface.
38+
func (t *Time) Scan(src any) error {
39+
if src == nil {
40+
return nil
41+
}
42+
43+
s, ok := src.(string)
44+
if !ok {
45+
return fmt.Errorf("error scanning time, got %+v", src)
46+
}
47+
48+
parsedT, err := time.Parse(rfc3339Milli, s)
49+
if err != nil {
50+
return err
51+
}
52+
53+
t.T = parsedT.UTC()
54+
55+
return nil
56+
}
57+
58+
func Now() *Time {
59+
return &Time{T: time.Now()}
60+
}
61+
62+
func (t *Time) MarshalText() ([]byte, error) {
63+
return []byte(t.String()), nil
64+
}
65+
66+
func (t *Time) UnmarshalText(data []byte) error {
67+
if len(data) == 0 {
68+
return nil
69+
}
70+
71+
parsedT, err := ParseTime(string(data))
72+
if err != nil {
73+
return err
74+
}
75+
76+
t.T = parsedT.T.UTC()
77+
78+
return nil
79+
}

0 commit comments

Comments
 (0)