Add Timestamp type for db
This commit is contained in:
parent
6a837d28c6
commit
b7b581ff5a
64
pkg/db/timestamp.go
Normal file
64
pkg/db/timestamp.go
Normal file
@ -0,0 +1,64 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Timestamp is a type that wraps `time.Time`. It implements `driver.Value` and `json.Marshal` to
|
||||
// store its value as an integer, a Unix timestamp in milliseconds.
|
||||
//
|
||||
// It uses type embedding (`struct { time.Time }`), instead of making it simply a typedef of
|
||||
// `time.Time`, because that keeps methods on `time.Time` (like Add, UnixMilli, etc.) intact and
|
||||
// exposed on instances of Timestamp.
|
||||
type Timestamp struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
func TimestampFromUnix(num int64) Timestamp {
|
||||
return Timestamp{time.Unix(num, 0)}
|
||||
}
|
||||
func TimestampFromUnixMilli(num int64) Timestamp {
|
||||
return Timestamp{time.UnixMilli(num)}
|
||||
}
|
||||
|
||||
// TimestampNow returns a new Timestamp corresponding to the current time, rounded to the nearest millisecond.
|
||||
func TimestampNow() Timestamp {
|
||||
return Timestamp{time.Now().Round(time.Millisecond)}
|
||||
}
|
||||
|
||||
// ------------
|
||||
// driver.Value
|
||||
// ------------
|
||||
|
||||
func (t Timestamp) Value() (driver.Value, error) {
|
||||
return t.UnixMilli(), nil
|
||||
}
|
||||
|
||||
func (t *Timestamp) Scan(src any) error {
|
||||
val, isOk := src.(int64)
|
||||
if !isOk {
|
||||
return fmt.Errorf("incompatible type for Timestamp: %#v", src)
|
||||
}
|
||||
*t = TimestampFromUnixMilli(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// json.Marshal / Unmarshal
|
||||
// ------------------------
|
||||
|
||||
func (t Timestamp) MarshalJSON() ([]byte, error) {
|
||||
return fmt.Appendf(nil, "%d", t.UnixMilli()), nil
|
||||
}
|
||||
|
||||
func (t *Timestamp) UnmarshalJSON(b []byte) error {
|
||||
ms, err := strconv.ParseInt(string(b), 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid timestamp %q: %w", string(b), err)
|
||||
}
|
||||
*t = TimestampFromUnixMilli(ms)
|
||||
return nil
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user