Created
July 9, 2020 02:55
-
-
Save miclle/2a352c9b7eb0559f9d238d1266a9b7b0 to your computer and use it in GitHub Desktop.
golang timestamp type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package timestamp | |
import ( | |
"database/sql/driver" | |
"fmt" | |
"strings" | |
"time" | |
"github.com/araddon/dateparse" | |
"github.com/globalsign/mgo/bson" | |
) | |
// TimestampFormatLayout formatlayout, save in mysql | |
const TimestampFormatLayout = "2006-01-02 15:04:05" | |
// New return timestamp | |
func New() Timestamp { | |
return Timestamp{} | |
} | |
// NewWithTime return a specified time's Timestamp | |
func NewWithTime(t time.Time) Timestamp { | |
return Timestamp{Time: t} | |
} | |
// Now returns the current local time. | |
func Now() Timestamp { | |
return Timestamp{Time: time.Now()} | |
} | |
// Unix returns the local Time corresponding to the given Unix time, | |
func Unix(sec int64, nsec int64) Timestamp { | |
return Timestamp{time.Unix(sec, nsec)} | |
} | |
// Date return time with date | |
func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Timestamp { | |
return Timestamp{time.Date(year, month, day, hour, min, sec, nsec, loc)} | |
} | |
// AutoSet auto set type | |
func AutoSet(data interface{}, fields ...string) { | |
if m, ok := data.(map[string]interface{}); ok { | |
for _, field := range fields { | |
v, exists := m[field] | |
if !exists { | |
continue | |
} | |
if t, ok := v.(float64); ok { | |
m[field] = Unix(int64(t), 0) | |
} | |
if t, ok := v.(int64); ok { | |
m[field] = Unix(t, 0) | |
} | |
} | |
} | |
} | |
// -------------------------------------------------------------------- | |
// Timestamp unix timestamp | |
type Timestamp struct { | |
time.Time | |
} | |
// Pointer return timestamp point | |
func (t Timestamp) Pointer() *Timestamp { | |
return &t | |
} | |
// MarshalJSON implements the json.Marshaler interface. | |
func (t Timestamp) MarshalJSON() ([]byte, error) { | |
if t.IsZero() || t.Time.UnixNano() == time.Unix(0, 0).UnixNano() { | |
return []byte("null"), nil | |
} | |
ts := t.Unix() | |
stamp := fmt.Sprint(ts) | |
return []byte(stamp), nil | |
} | |
// UnmarshalJSON implements the json.Unmarshaler interface. | |
func (t *Timestamp) UnmarshalJSON(b []byte) error { | |
var ( | |
err error | |
str = strings.Replace(string(b), "\"", "", -1) | |
) | |
if str == "null" || str == "0" { | |
return nil | |
} | |
t.Time, err = dateparse.ParseAny(str) | |
return err | |
} | |
// -------------------------------------------------------------------- | |
// GetBSON implements the bson Getter interface | |
func (t Timestamp) GetBSON() (interface{}, error) { | |
if t.IsZero() || t.Time.UnixNano() == time.Unix(0, 0).UnixNano() { | |
return nil, nil | |
} | |
return t, nil | |
} | |
// SetBSON implements the bson Setter interface | |
func (t *Timestamp) SetBSON(raw bson.Raw) error { | |
var tm time.Time | |
if err := raw.Unmarshal(&tm); err != nil { | |
return err | |
} | |
t.Time = tm | |
return nil | |
} | |
// -------------------------------------------------------------------- | |
// Scan valueof time.Time | |
func (t *Timestamp) Scan(value interface{}) error { | |
if value == nil { | |
return nil | |
} | |
if v, ok := value.(time.Time); ok { | |
*t = Timestamp{v} | |
return nil | |
} | |
return fmt.Errorf("can not convert %v to timestamp", value) | |
} | |
// Value insert timestamp into mysql need this function. | |
func (t Timestamp) Value() (driver.Value, error) { | |
if t.IsZero() || t.Time.UnixNano() == time.Unix(0, 0).UnixNano() { | |
return nil, nil | |
} | |
return t.Time, nil | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package timestamp_test | |
import ( | |
"testing" | |
"time" | |
"github.com/globalsign/mgo/bson" | |
"github.com/stretchr/testify/assert" | |
"works.im/components/timestamp" | |
) | |
func TestTimestamp(t *testing.T) { | |
assert := assert.New(t) | |
now := timestamp.Now() | |
assert.NotNil(now) | |
uts := timestamp.Unix(1490328882, 0) | |
assert.NotNil(uts) | |
assert.Equal(uts.Unix(), int64(1490328882)) | |
date := timestamp.Date(2018, 11, 11, 0, 0, 0, 0, time.Local) | |
assert.NotNil(date) | |
assert.Equal(date.Year(), 2018) | |
assert.Equal(date.Month(), time.Month(11)) | |
assert.Equal(date.Day(), 11) | |
timestamp := timestamp.New() | |
assert.NotNil(timestamp) | |
err := timestamp.UnmarshalJSON([]byte("2018-11-15 17:56:17")) | |
assert.Nil(err) | |
assert.False(timestamp.IsZero()) | |
err = timestamp.UnmarshalJSON([]byte("1490328882")) | |
assert.Nil(err) | |
assert.False(timestamp.IsZero()) | |
b, err := timestamp.MarshalJSON() | |
assert.Nil(err) | |
assert.True(len(b) > 0) | |
assert.Equal(string(b), "1490328882") | |
fttit, err := timestamp.GetBSON() | |
assert.Nil(err) | |
assert.NotNil(fttit) | |
err = timestamp.SetBSON(bson.Raw{}) | |
assert.NotNil(err) | |
err = timestamp.SetBSON(bson.Raw{ | |
Kind: 0x09, | |
Data: []byte{128, 251, 42, 98, 85, 1, 0, 0}, | |
}) | |
assert.Nil(err) | |
err = timestamp.Scan(time.Now()) | |
assert.Nil(err) | |
assert.False(timestamp.IsZero()) | |
value, err := timestamp.Value() | |
assert.Nil(err) | |
assert.NotNil(value) | |
_, ok := value.(time.Time) | |
assert.True(ok) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment