package model import ( "encoding/json" "io" "log" "regexp" "strconv" "time" ) type DateTime int64 var datetimeLayout = "2006-01-02T15:04:05Z0700" func NewDateTime(milli int64) *DateTime { date := DateTime(milli) return &date } func NewDateTimeIn(seconds int) DateTime { return DateTime( time.Now().In(time.UTC).Add(time.Duration(seconds) * time.Second).UnixMilli()) } func NewDateTimeFrom(t time.Time) *DateTime { date := DateTime(t.In(time.UTC).UnixMilli()) return &date } func Now() DateTime { return DateTime(time.Now().In(time.UTC).UnixMilli()) } func (d DateTime) String() string { return time.UnixMilli(int64(d)).In(time.UTC).Format(datetimeLayout) } func (d DateTime) MarshalJSON() ([]byte, error) { return json.Marshal(time.UnixMilli(int64(d)).In(time.UTC)) } func (d DateTime) MarshalGQL(w io.Writer) { _, err := w.Write([]byte(strconv.Quote(d.String()))) if err != nil { log.Default().Println(err) } } func (d *DateTime) UnixMilli() int64 { return int64(*d) } func (d *DateTime) UnmarshalGQL(v interface{}) error { switch v := v.(type) { case float64: *d = DateTime(v) case int: *d = DateTime(v) case time.Time: *d = DateTime(v.In(time.UTC).UnixMilli()) case string: if regexp.MustCompile(`^\d{13}$`).MatchString(v) { if i, err := strconv.Atoi(v); err == nil { *d = DateTime(i) return nil } } t, err := time.Parse(datetimeLayout, v) if err != nil { return err } *d = DateTime(t.In(time.UTC).UnixMilli()) case DateTime: *d = v } return nil }