datetime.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package model
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/mailru/easyjson/jlexer"
  6. "github.com/mailru/easyjson/jwriter"
  7. "io"
  8. "log"
  9. "regexp"
  10. "strconv"
  11. "time"
  12. )
  13. type DateTime int64
  14. var datetimeLayout = "2006-01-02T15:04:05Z0700"
  15. func NewDateTime(milli int64) *DateTime {
  16. date := DateTime(milli)
  17. return &date
  18. }
  19. func NewDateTimeIn(seconds int64) DateTime {
  20. return DateTime(
  21. time.Unix(seconds, 0).
  22. In(time.UTC).
  23. UnixMilli())
  24. }
  25. func NewDateTimeFrom(t time.Time) *DateTime {
  26. date := DateTime(t.In(time.UTC).UnixMilli())
  27. return &date
  28. }
  29. func Now() DateTime {
  30. return DateTime(time.Now().In(time.UTC).UnixMilli())
  31. }
  32. func (d DateTime) String() string {
  33. return time.UnixMilli(int64(d)).In(time.UTC).Format(datetimeLayout)
  34. }
  35. func (d DateTime) MarshalJSON() ([]byte, error) {
  36. return json.Marshal(time.UnixMilli(int64(d)).In(time.UTC))
  37. }
  38. func (d DateTime) MarshalGQL(w io.Writer) {
  39. _, err := w.Write([]byte(strconv.Quote(d.String())))
  40. if err != nil {
  41. log.Default().Println(err)
  42. }
  43. }
  44. func (d *DateTime) UnixMilli() int64 {
  45. return int64(*d)
  46. }
  47. func (d *DateTime) UnmarshalGQL(v interface{}) error {
  48. switch v := v.(type) {
  49. case float64:
  50. *d = DateTime(v)
  51. case int:
  52. *d = DateTime(v)
  53. case time.Time:
  54. *d = DateTime(v.In(time.UTC).UnixMilli())
  55. case string:
  56. if regexp.MustCompile(`^\d{13}$`).MatchString(v) {
  57. if i, err := strconv.Atoi(v); err == nil {
  58. *d = DateTime(i)
  59. return nil
  60. }
  61. }
  62. t, err := time.Parse(datetimeLayout, v)
  63. if err != nil {
  64. return err
  65. }
  66. *d = DateTime(t.In(time.UTC).UnixMilli())
  67. case DateTime:
  68. *d = v
  69. }
  70. return nil
  71. }
  72. func (d *DateTime) Scan(src any) error {
  73. if t, ok := src.(int64); ok {
  74. *d = NewDateTimeIn(t)
  75. return nil
  76. }
  77. return fmt.Errorf("cannot scan %T into DateTime", src)
  78. }
  79. func (d *DateTime) MarshalEasyJSON(w *jwriter.Writer) {
  80. w.RawString(fmt.Sprintf("%d", d.UnixMilli()))
  81. }
  82. func (d *DateTime) UnmarshalEasyJSON(l *jlexer.Lexer) {
  83. if l.IsNull() {
  84. l.Skip()
  85. *d = DateTime(0)
  86. } else {
  87. *d = DateTime(l.Int64())
  88. }
  89. }