Skip to content

Instantly share code, notes, and snippets.

@miclle
Created July 9, 2020 02:55
Show Gist options
  • Save miclle/2a352c9b7eb0559f9d238d1266a9b7b0 to your computer and use it in GitHub Desktop.
Save miclle/2a352c9b7eb0559f9d238d1266a9b7b0 to your computer and use it in GitHub Desktop.
golang timestamp type
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
}
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