package rfctime import ( "encoding/json" "errors" "fmt" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/bsoncodec" "go.mongodb.org/mongo-driver/bson/bsonrw" "go.mongodb.org/mongo-driver/bson/bsontype" "gogs.mikescher.com/BlackForestBytes/goext/langext" "reflect" "strconv" "time" ) type UnixNanoTime time.Time func (t UnixNanoTime) Time() time.Time { return time.Time(t) } func (t UnixNanoTime) MarshalBinary() ([]byte, error) { return (time.Time)(t).MarshalBinary() } func (t *UnixNanoTime) UnmarshalBinary(data []byte) error { return (*time.Time)(t).UnmarshalBinary(data) } func (t UnixNanoTime) GobEncode() ([]byte, error) { return (time.Time)(t).GobEncode() } func (t *UnixNanoTime) GobDecode(data []byte) error { return (*time.Time)(t).GobDecode(data) } func (t *UnixNanoTime) UnmarshalJSON(data []byte) error { str := "" if err := json.Unmarshal(data, &str); err != nil { return err } t0, err := strconv.ParseInt(str, 10, 64) if err != nil { return err } *t = UnixNanoTime(time.Unix(0, t0)) return nil } func (t UnixNanoTime) MarshalJSON() ([]byte, error) { str := strconv.FormatInt(t.Time().UnixNano(), 10) return json.Marshal(str) } func (t UnixNanoTime) MarshalText() ([]byte, error) { return []byte(strconv.FormatInt(t.Time().UnixNano(), 10)), nil } func (t *UnixNanoTime) UnmarshalText(data []byte) error { t0, err := strconv.ParseInt(string(data), 10, 64) if err != nil { return err } *t = UnixNanoTime(time.Unix(0, t0)) return nil } func (t *UnixNanoTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { if bt == bson.TypeNull { // we can't set nil in UnmarshalBSONValue (so we use default(struct)) // Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values // https://stackoverflow.com/questions/75167597 // https://jira.mongodb.org/browse/GODRIVER-2252 *t = UnixNanoTime{} return nil } if bt != bson.TypeDateTime { return errors.New(fmt.Sprintf("cannot unmarshal %v into UnixNanoTime", bt)) } var tt time.Time err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt) if err != nil { return err } *t = UnixNanoTime(tt) return nil } func (t UnixNanoTime) MarshalBSONValue() (bsontype.Type, []byte, error) { return bson.MarshalValue(time.Time(t)) } func (t UnixNanoTime) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { if val.Kind() == reflect.Ptr && val.IsNil() { if !val.CanSet() { return errors.New("ValueUnmarshalerDecodeValue") } val.Set(reflect.New(val.Type().Elem())) } tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr) if err != nil { return err } if val.Kind() == reflect.Ptr && len(src) == 0 { val.Set(reflect.Zero(val.Type())) return nil } err = t.UnmarshalBSONValue(tp, src) if err != nil { return err } if val.Kind() == reflect.Ptr { val.Set(reflect.ValueOf(&t)) } else { val.Set(reflect.ValueOf(t)) } return nil } func (t UnixNanoTime) Serialize() string { return strconv.FormatInt(t.Time().UnixNano(), 10) } func (t UnixNanoTime) After(u AnyTime) bool { return t.Time().After(tt(u)) } func (t UnixNanoTime) Before(u AnyTime) bool { return t.Time().Before(tt(u)) } func (t UnixNanoTime) Equal(u AnyTime) bool { return t.Time().Equal(tt(u)) } func (t UnixNanoTime) IsZero() bool { return t.Time().IsZero() } func (t UnixNanoTime) Date() (year int, month time.Month, day int) { return t.Time().Date() } func (t UnixNanoTime) Year() int { return t.Time().Year() } func (t UnixNanoTime) Month() time.Month { return t.Time().Month() } func (t UnixNanoTime) Day() int { return t.Time().Day() } func (t UnixNanoTime) Weekday() time.Weekday { return t.Time().Weekday() } func (t UnixNanoTime) ISOWeek() (year, week int) { return t.Time().ISOWeek() } func (t UnixNanoTime) Clock() (hour, min, sec int) { return t.Time().Clock() } func (t UnixNanoTime) Hour() int { return t.Time().Hour() } func (t UnixNanoTime) Minute() int { return t.Time().Minute() } func (t UnixNanoTime) Second() int { return t.Time().Second() } func (t UnixNanoTime) Nanosecond() int { return t.Time().Nanosecond() } func (t UnixNanoTime) YearDay() int { return t.Time().YearDay() } func (t UnixNanoTime) Add(d time.Duration) UnixNanoTime { return UnixNanoTime(t.Time().Add(d)) } func (t UnixNanoTime) Sub(u AnyTime) time.Duration { return t.Time().Sub(tt(u)) } func (t UnixNanoTime) AddDate(years int, months int, days int) UnixNanoTime { return UnixNanoTime(t.Time().AddDate(years, months, days)) } func (t UnixNanoTime) Unix() int64 { return t.Time().Unix() } func (t UnixNanoTime) UnixMilli() int64 { return t.Time().UnixNano() } func (t UnixNanoTime) UnixMicro() int64 { return t.Time().UnixMicro() } func (t UnixNanoTime) UnixNano() int64 { return t.Time().UnixNano() } func (t UnixNanoTime) Format(layout string) string { return t.Time().Format(layout) } func (t UnixNanoTime) GoString() string { return t.Time().GoString() } func (t UnixNanoTime) String() string { return t.Time().String() } func (t UnixNanoTime) Location() *time.Location { return t.Time().Location() } func NewUnixNano(t time.Time) UnixNanoTime { return UnixNanoTime(t) } func NewUnixNanoPtr(t *time.Time) *UnixNanoTime { if t == nil { return nil } return langext.Ptr(UnixNanoTime(*t)) } func NowUnixNano() UnixNanoTime { return UnixNanoTime(time.Now()) }