Local_datetime.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright (c) 2015 qianqiusoft.com
  2. // Licensed to You under the GNU Affero GPL v3
  3. // See the LICENSE file at git.qianqiusoft.com/qianqiusoft/light-vocation/LICENSE
  4. // http://www.gnu.org/licenses/why-affero-gpl.en.html
  5. package models
  6. import (
  7. "fmt"
  8. "strings"
  9. "time"
  10. "github.com/astaxie/beego/orm"
  11. )
  12. // datetime values like 2006-01-02 15:04:05
  13. type LocalDateTime time.Time
  14. const formatDateTime = "2006-01-02 15:04:05"
  15. const nilDateTimeStr = "0001-01-01 00:00:00"
  16. func NowLocal() LocalDateTime {
  17. return LocalDateTime(time.Now())
  18. }
  19. func nilDateTime() LocalDateTime {
  20. nilDateTime, _ := timeParse(formatDateTime, nilDateTimeStr) //time.ParseInLocation(formatDate, nilDateStr, time.Local)
  21. return LocalDateTime(nilDateTime)
  22. }
  23. func isNilDateTime(tval time.Time) bool {
  24. return tval.Format(formatDateTime) == nilDateTimeStr
  25. }
  26. // Value return the datatime value
  27. func (e LocalDateTime) IsNilDateTime() bool {
  28. return isNilDateTime(e.Value())
  29. }
  30. // Value return the datatime value
  31. func (e LocalDateTime) Value() time.Time {
  32. return time.Time(e)
  33. }
  34. // Set set the time.Time to datatime
  35. func (e *LocalDateTime) Set(d time.Time) {
  36. //fmt.Println("-------------------- LocalDateTime Set ")
  37. *e = LocalDateTime(d)
  38. }
  39. // String return the time's String
  40. func (e *LocalDateTime) String() string {
  41. return e.Value().String()
  42. }
  43. // FieldType return the enum TypeDateTimeField
  44. func (e *LocalDateTime) FieldType() int {
  45. return orm.TypeDateTimeField
  46. }
  47. // SetRaw convert the string or time.Time to DateTimeField
  48. func (e *LocalDateTime) SetRaw(value interface{}) error {
  49. //fmt.Println("-------------------- LocalDateTime SetRaw ")
  50. if value == nil {
  51. *e = nilDateTime()
  52. return nil
  53. }
  54. switch d := value.(type) {
  55. case time.Time:
  56. //fmt.Println("--------------------time.time val is ", d.Format(formatDateTime))
  57. if isNilDateTime(d) {
  58. *e = nilDateTime()
  59. } else {
  60. e.Set(d)
  61. }
  62. case string:
  63. //fmt.Println("--------------------string val is ", d)
  64. v, err := timeParse(d, formatDateTime)
  65. if err == nil {
  66. e.Set(v)
  67. }
  68. return err
  69. default:
  70. return fmt.Errorf("<DateTimeField.SetRaw> unknown value `%s`", value)
  71. }
  72. return nil
  73. }
  74. // RawValue return the datatime value
  75. func (e *LocalDateTime) RawValue() interface{} {
  76. //fmt.Println("-------------------- LocalDateTime RawValue ")
  77. //fmt.Println("--------------------RawValue val is ", e.Value().Format(formatDateTime))
  78. return e.Value()
  79. }
  80. // parse time to string with location
  81. func timeParse(dateString, format string) (time.Time, error) {
  82. // this
  83. tp, err := time.ParseInLocation(format, dateString, orm.DefaultTimeLoc)
  84. return tp, err
  85. }
  86. func (t *LocalDateTime) UnmarshalJSON(data []byte) (err error) {
  87. if data[0] == '"' && data[len(data)-1] == '"' {
  88. data = data[1 : len(data)-1]
  89. }
  90. dataStr := strings.TrimSpace(string(data))
  91. if dataStr == "" {
  92. *t = nilDateTime()
  93. return nil
  94. }
  95. var now time.Time
  96. if strings.Index(dataStr, "T") > 0 {
  97. // there is t with the date string
  98. now, err = time.ParseInLocation(time.RFC3339Nano, dataStr, time.Local)
  99. if err != nil {
  100. now, err = time.ParseInLocation(time.RFC3339, dataStr, time.Local)
  101. }
  102. // if t date, we format and parse withe utc againt
  103. // special special........
  104. if err == nil {
  105. now, err = timeParse(now.Format(formatDateTime), formatDateTime)
  106. }
  107. } else {
  108. if len(dataStr) == 19 {
  109. if dataStr == "0000-00-00 00:00:00" {
  110. dataStr = nilDateTimeStr
  111. }
  112. } else if len(dataStr) == 10 {
  113. // only date
  114. dataStr += " 00:00:00"
  115. } else if len(dataStr) == 13 {
  116. // only hour
  117. dataStr += ":00:00"
  118. } else if len(dataStr) == 16 {
  119. // only hour
  120. dataStr += ":00"
  121. }
  122. //fmt.Println("---------------before json unmarshal ", dataStr)
  123. now, err = timeParse(dataStr, formatDateTime) //time.ParseInLocation(formatDateTime, dataStr, time.Local)
  124. //fmt.Println("---------------after json unmarshal ", now.Format(formatDateTime))
  125. }
  126. *t = LocalDateTime(now)
  127. return
  128. }
  129. func (t LocalDateTime) MarshalJSON() ([]byte, error) {
  130. if isNilDateTime(t.Value()) {
  131. return []byte{'"', '"'}, nil
  132. }
  133. b := make([]byte, 0, len(formatDateTime)+2)
  134. b = append(b, '"')
  135. b = append(b, []byte(time.Time(t).Format(formatDateTime))...)
  136. b = append(b, '"')
  137. return b, nil
  138. }
  139. var _ orm.Fielder = new(LocalDateTime)