now.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package utils
  2. import (
  3. "errors"
  4. "regexp"
  5. "time"
  6. )
  7. func (now *Now) BeginningOfMinute() time.Time {
  8. return now.Truncate(time.Minute)
  9. }
  10. func (now *Now) BeginningOfHour() time.Time {
  11. y, m, d := now.Date()
  12. return time.Date(y, m, d, now.Time.Hour(), 0, 0, 0, now.Time.Location())
  13. }
  14. func (now *Now) BeginningOfDay() time.Time {
  15. y, m, d := now.Date()
  16. return time.Date(y, m, d, 0, 0, 0, 0, now.Time.Location())
  17. }
  18. func (now *Now) BeginningOfWeek() time.Time {
  19. t := now.BeginningOfDay()
  20. weekday := int(t.Weekday())
  21. if WeekStartDay != time.Sunday {
  22. weekStartDayInt := int(WeekStartDay)
  23. if weekday < weekStartDayInt {
  24. weekday = weekday + 7 - weekStartDayInt
  25. } else {
  26. weekday = weekday - weekStartDayInt
  27. }
  28. }
  29. return t.AddDate(0, 0, -weekday)
  30. }
  31. func (now *Now) BeginningOfMonth() time.Time {
  32. y, m, _ := now.Date()
  33. return time.Date(y, m, 1, 0, 0, 0, 0, now.Location())
  34. }
  35. func (now *Now) BeginningOfQuarter() time.Time {
  36. month := now.BeginningOfMonth()
  37. offset := (int(month.Month()) - 1) % 3
  38. return month.AddDate(0, -offset, 0)
  39. }
  40. func (now *Now) BeginningOfYear() time.Time {
  41. y, _, _ := now.Date()
  42. return time.Date(y, time.January, 1, 0, 0, 0, 0, now.Location())
  43. }
  44. func (now *Now) EndOfMinute() time.Time {
  45. return now.BeginningOfMinute().Add(time.Minute - time.Nanosecond)
  46. }
  47. func (now *Now) EndOfHour() time.Time {
  48. return now.BeginningOfHour().Add(time.Hour - time.Nanosecond)
  49. }
  50. func (now *Now) EndOfDay() time.Time {
  51. y, m, d := now.Date()
  52. return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), now.Location())
  53. }
  54. func (now *Now) EndOfWeek() time.Time {
  55. return now.BeginningOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond)
  56. }
  57. func (now *Now) EndOfMonth() time.Time {
  58. return now.BeginningOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond)
  59. }
  60. func (now *Now) EndOfQuarter() time.Time {
  61. return now.BeginningOfQuarter().AddDate(0, 3, 0).Add(-time.Nanosecond)
  62. }
  63. func (now *Now) EndOfYear() time.Time {
  64. return now.BeginningOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond)
  65. }
  66. func (now *Now) Monday() time.Time {
  67. t := now.BeginningOfDay()
  68. weekday := int(t.Weekday())
  69. if weekday == 0 {
  70. weekday = 7
  71. }
  72. return t.AddDate(0, 0, -weekday+1)
  73. }
  74. func (now *Now) Sunday() time.Time {
  75. t := now.BeginningOfDay()
  76. weekday := int(t.Weekday())
  77. if weekday == 0 {
  78. return t
  79. }
  80. return t.AddDate(0, 0, (7 - weekday))
  81. }
  82. func (now *Now) EndOfSunday() time.Time {
  83. return New(now.Sunday()).EndOfDay()
  84. }
  85. func parseWithFormat(str string) (t time.Time, err error) {
  86. for _, format := range TimeFormats {
  87. t, err = time.Parse(format, str)
  88. if err == nil {
  89. return
  90. }
  91. }
  92. err = errors.New("Can't parse string as time: " + str)
  93. return
  94. }
  95. var hasTimeRegexp = regexp.MustCompile(`(\s+|^\s*)\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))\s*$`)
  96. var onlyTimeRegexp = regexp.MustCompile(`^\s*\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))\s*$`)
  97. func (now *Now) Parse(strs ...string) (t time.Time, err error) {
  98. var (
  99. setCurrentTime bool
  100. parseTime []int
  101. currentTime = []int{now.Nanosecond(), now.Second(), now.Minute(), now.Hour(), now.Day(), int(now.Month()), now.Year()}
  102. currentLocation = now.Location()
  103. onlyTimeInStr = true
  104. )
  105. for _, str := range strs {
  106. hasTimeInStr := hasTimeRegexp.MatchString(str)
  107. onlyTimeInStr = hasTimeInStr && onlyTimeInStr && onlyTimeRegexp.MatchString(str)
  108. if t, err = parseWithFormat(str); err == nil {
  109. location := t.Location()
  110. if location.String() == "UTC" {
  111. location = currentLocation
  112. }
  113. parseTime = []int{t.Nanosecond(), t.Second(), t.Minute(), t.Hour(), t.Day(), int(t.Month()), t.Year()}
  114. for i, v := range parseTime {
  115. if hasTimeInStr && i <= 3 {
  116. continue
  117. }
  118. if v == 0 {
  119. if setCurrentTime {
  120. parseTime[i] = currentTime[i]
  121. }
  122. } else {
  123. setCurrentTime = true
  124. }
  125. if onlyTimeInStr {
  126. if i == 4 || i == 5 {
  127. parseTime[i] = currentTime[i]
  128. continue
  129. }
  130. }
  131. }
  132. t = time.Date(parseTime[6], time.Month(parseTime[5]), parseTime[4], parseTime[3], parseTime[2], parseTime[1], parseTime[0], location)
  133. currentTime = []int{t.Nanosecond(), t.Second(), t.Minute(), t.Hour(), t.Day(), int(t.Month()), t.Year()}
  134. }
  135. }
  136. return
  137. }
  138. func (now *Now) MustParse(strs ...string) (t time.Time) {
  139. t, err := now.Parse(strs...)
  140. if err != nil {
  141. panic(err)
  142. }
  143. return t
  144. }
  145. func (now *Now) Between(begin, end string) bool {
  146. beginTime := now.MustParse(begin)
  147. endTime := now.MustParse(end)
  148. return now.After(beginTime) && now.Before(endTime)
  149. }
  150. var WeekStartDay = time.Sunday
  151. var TimeFormats = []string{"1/2/2006", "1/2/2006 15:4:5", "2006", "2006-1", "2006-1-2", "2006-1-2 15", "2006-1-2 15:4", "2006-1-2 15:4:5", "1-2", "15:4:5", "15:4", "15", "15:4:5 Jan 2, 2006 MST", "2006-01-02 15:04:05.999999999 -0700 MST"}
  152. type Now struct {
  153. time.Time
  154. }
  155. func New(t time.Time) *Now {
  156. return &Now{t}
  157. }
  158. func BeginningOfMinute() time.Time {
  159. return New(time.Now()).BeginningOfMinute()
  160. }
  161. func BeginningOfHour() time.Time {
  162. return New(time.Now()).BeginningOfHour()
  163. }
  164. func BeginningOfDay() time.Time {
  165. return New(time.Now()).BeginningOfDay()
  166. }
  167. func BeginningOfWeek() time.Time {
  168. return New(time.Now()).BeginningOfWeek()
  169. }
  170. func BeginningOfMonth() time.Time {
  171. return New(time.Now()).BeginningOfMonth()
  172. }
  173. func BeginningOfQuarter() time.Time {
  174. return New(time.Now()).BeginningOfQuarter()
  175. }
  176. func BeginningOfYear() time.Time {
  177. return New(time.Now()).BeginningOfYear()
  178. }
  179. func EndOfMinute() time.Time {
  180. return New(time.Now()).EndOfMinute()
  181. }
  182. func EndOfHour() time.Time {
  183. return New(time.Now()).EndOfHour()
  184. }
  185. func EndOfDay() time.Time {
  186. return New(time.Now()).EndOfDay()
  187. }
  188. func EndOfWeek() time.Time {
  189. return New(time.Now()).EndOfWeek()
  190. }
  191. func EndOfMonth() time.Time {
  192. return New(time.Now()).EndOfMonth()
  193. }
  194. func EndOfQuarter() time.Time {
  195. return New(time.Now()).EndOfQuarter()
  196. }
  197. func EndOfYear() time.Time {
  198. return New(time.Now()).EndOfYear()
  199. }
  200. func Monday() time.Time {
  201. return New(time.Now()).Monday()
  202. }
  203. func Sunday() time.Time {
  204. return New(time.Now()).Sunday()
  205. }
  206. func EndOfSunday() time.Time {
  207. return New(time.Now()).EndOfSunday()
  208. }
  209. func Parse(strs ...string) (time.Time, error) {
  210. return New(time.Now()).Parse(strs...)
  211. }
  212. func ParseInLocation(loc *time.Location, strs ...string) (time.Time, error) {
  213. return New(time.Now().In(loc)).Parse(strs...)
  214. }
  215. func MustParse(strs ...string) time.Time {
  216. return New(time.Now()).MustParse(strs...)
  217. }
  218. func MustParseInLocation(loc *time.Location, strs ...string) time.Time {
  219. return New(time.Now().In(loc)).MustParse(strs...)
  220. }
  221. func Between(time1, time2 string) bool {
  222. return New(time.Now()).Between(time1, time2)
  223. }