marion 5 tahun lalu
induk
melakukan
8d914547eb
3 mengubah file dengan 159 tambahan dan 3 penghapusan
  1. 54 1
      utils/date/date.go
  2. 51 1
      utils/date/datetime.go
  3. 54 1
      utils/date/time.go

+ 54 - 1
utils/date/date.go

@@ -2,7 +2,10 @@ package date
 
 import (
 	"database/sql/driver"
+	"encoding/binary"
 	"errors"
+	"fmt"
+	"github.com/vmihailenco/msgpack"
 	"strings"
 	"time"
 )
@@ -11,6 +14,10 @@ type Date time.Time
 
 const NormalDateFormat = "2006-01-02"
 
+func init() {
+	msgpack.RegisterExt(1, (*Date)(nil))
+}
+
 func (t Date) MarshalJSON() ([]byte, error) {
 	if y := t.Year(); y < 0 || y >= 10000 {
 		return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
@@ -39,6 +46,48 @@ func (t *Date) UnmarshalJSON(value []byte) error {
 	return nil
 }
 
+func (t *Date) MarshalMsgpack() ([]byte, error) {
+	b := make([]byte, 8)
+	binary.BigEndian.PutUint32(b, uint32(t.Unix()))
+	binary.BigEndian.PutUint32(b[4:], uint32(t.Nanosecond()))
+	return b, nil
+}
+
+func (t *Date) UnmarshalMsgpack(b []byte) error {
+	if len(b) != 8 {
+		return fmt.Errorf("invalid data length: got %d, wanted 8", len(b))
+	}
+	sec := binary.BigEndian.Uint32(b)
+	usec := binary.BigEndian.Uint32(b[4:])
+	*t = Date(time.Unix(int64(sec), int64(usec)))
+	return nil
+}
+
+func DateRegisterExt() {
+	t := Date(time.Unix(123456789, 123))
+	b, err := msgpack.Marshal(&t)
+	if err != nil {
+		panic(err)
+	}
+
+	var v interface{}
+	err = msgpack.Unmarshal(b, &v)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(v.(*Date).UTC())
+
+	tm := &Date{}
+	err = msgpack.Unmarshal(b, tm)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(tm.UTC())
+
+	// Output: 1973-11-29 21:33:09.000000123 +0000 UTC
+	// 1973-11-29 21:33:09.000000123 +0000 UTC
+}
+
 func (t Date) MarshalText() ([]byte, error) {
 	if y := t.Year(); y < 0 || y >= 10000 {
 		return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
@@ -59,7 +108,11 @@ func (t Date) FromString(str string) Date {
 
 func ParseDate(str string) Date {
 	str = dateStrFormat(str)
-	tm, err := time.Parse(NormalDateFormat, str)
+	return ParseDateFormat(str, NormalDateFormat)
+}
+func ParseDateFormat(str string, format string) Date {
+	str = strings.TrimSpace(str)
+	tm, err := time.ParseInLocation(format, str, time.Local)
 	if nil != err {
 		return Unix(0, 0).ToDate()
 	}

+ 51 - 1
utils/date/datetime.go

@@ -2,7 +2,10 @@ package date
 
 import (
 	"database/sql/driver"
+	"encoding/binary"
 	"errors"
+	"fmt"
+	"github.com/vmihailenco/msgpack"
 	"regexp"
 	"strings"
 	"time"
@@ -17,6 +20,7 @@ var (
 )
 
 func init() {
+	msgpack.RegisterExt(0, (*Datetime)(nil))
 	datePattern, _ = regexp.Compile(`([-:\s])(\d)([-:\s])`)
 }
 
@@ -48,6 +52,48 @@ func (t *Datetime) UnmarshalJSON(value []byte) error {
 	return nil
 }
 
+func (t *Datetime) MarshalMsgpack() ([]byte, error) {
+	b := make([]byte, 8)
+	binary.BigEndian.PutUint32(b, uint32(t.Unix()))
+	binary.BigEndian.PutUint32(b[4:], uint32(t.Nanosecond()))
+	return b, nil
+}
+
+func (t *Datetime) UnmarshalMsgpack(b []byte) error {
+	if len(b) != 8 {
+		return fmt.Errorf("invalid data length: got %d, wanted 8", len(b))
+	}
+	sec := binary.BigEndian.Uint32(b)
+	usec := binary.BigEndian.Uint32(b[4:])
+	*t = Datetime(time.Unix(int64(sec), int64(usec)))
+	return nil
+}
+
+func DatetimeRegisterExt() {
+	t := Datetime(time.Unix(123456789, 123))
+	b, err := msgpack.Marshal(&t)
+	if err != nil {
+		panic(err)
+	}
+
+	var v interface{}
+	err = msgpack.Unmarshal(b, &v)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(v.(*Datetime).UTC())
+
+	tm := &Datetime{}
+	err = msgpack.Unmarshal(b, tm)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(tm.UTC())
+
+	// Output: 1973-11-29 21:33:09.000000123 +0000 UTC
+	// 1973-11-29 21:33:09.000000123 +0000 UTC
+}
+
 func (t Datetime) MarshalText() ([]byte, error) {
 	if y := t.Year(); y < 0 || y >= 10000 {
 		return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
@@ -68,7 +114,11 @@ func (t Datetime) FromString(str string) Datetime {
 
 func ParseDatetime(str string) Datetime {
 	str = dateStrFormat(str)
-	tm, err := time.Parse(NormalDatetimeFormat, str)
+	return ParseDatetimeFormat(str, NormalDatetimeFormat)
+}
+func ParseDatetimeFormat(str, format string) Datetime {
+	str = strings.TrimSpace(str)
+	tm, err := time.ParseInLocation(format, str, time.Local)
 	if nil != err {
 		return Unix(0, 0)
 	}

+ 54 - 1
utils/date/time.go

@@ -2,7 +2,10 @@ package date
 
 import (
 	"database/sql/driver"
+	"encoding/binary"
 	"errors"
+	"fmt"
+	"github.com/vmihailenco/msgpack"
 	"strings"
 	"time"
 )
@@ -11,6 +14,10 @@ type Time time.Time
 
 const NormalTimeFormat = "15:04:05"
 
+func init() {
+	msgpack.RegisterExt(2, (*Time)(nil))
+}
+
 func (t Time) MarshalJSON() ([]byte, error) {
 	if y := t.Year(); y < 0 || y >= 10000 {
 		return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
@@ -39,6 +46,48 @@ func (t *Time) UnmarshalJSON(value []byte) error {
 	return nil
 }
 
+func (t *Time) MarshalMsgpack() ([]byte, error) {
+	b := make([]byte, 8)
+	binary.BigEndian.PutUint32(b, uint32(t.Unix()))
+	binary.BigEndian.PutUint32(b[4:], uint32(t.Nanosecond()))
+	return b, nil
+}
+
+func (t *Time) UnmarshalMsgpack(b []byte) error {
+	if len(b) != 8 {
+		return fmt.Errorf("invalid data length: got %d, wanted 8", len(b))
+	}
+	sec := binary.BigEndian.Uint32(b)
+	usec := binary.BigEndian.Uint32(b[4:])
+	*t = Time(time.Unix(int64(sec), int64(usec)))
+	return nil
+}
+
+func TimeRegisterExt() {
+	t := Time(time.Unix(123456789, 123))
+	b, err := msgpack.Marshal(&t)
+	if err != nil {
+		panic(err)
+	}
+
+	var v interface{}
+	err = msgpack.Unmarshal(b, &v)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(v.(*Time).UTC())
+
+	tm := &Time{}
+	err = msgpack.Unmarshal(b, tm)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(tm.UTC())
+
+	// Output: 1973-11-29 21:33:09.000000123 +0000 UTC
+	// 1973-11-29 21:33:09.000000123 +0000 UTC
+}
+
 func (t Time) MarshalText() ([]byte, error) {
 	if y := t.Year(); y < 0 || y >= 10000 {
 		return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
@@ -59,7 +108,11 @@ func (t Time) FromString(str string) Time {
 
 func ParseTime(str string) Time {
 	str = dateStrFormat(str)
-	tm, err := time.Parse(NormalTimeFormat, str)
+	return ParseTimeFormat(str, NormalTimeFormat)
+}
+func ParseTimeFormat(str string, format string) Time {
+	str = strings.TrimSpace(str)
+	tm, err := time.ParseInLocation(format, str, time.Local)
 	if nil != err {
 		return Unix(0, 0).ToTime()
 	}