now.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package now
  2. import (
  3. "errors"
  4. "regexp"
  5. "time"
  6. )
  7. // BeginningOfMinute beginning of minute
  8. func (now *Now) BeginningOfMinute() time.Time {
  9. return now.Truncate(time.Minute)
  10. }
  11. // BeginningOfHour beginning of hour
  12. func (now *Now) BeginningOfHour() time.Time {
  13. y, m, d := now.Date()
  14. return time.Date(y, m, d, now.Time.Hour(), 0, 0, 0, now.Time.Location())
  15. }
  16. // BeginningOfDay beginning of day
  17. func (now *Now) BeginningOfDay() time.Time {
  18. y, m, d := now.Date()
  19. return time.Date(y, m, d, 0, 0, 0, 0, now.Time.Location())
  20. }
  21. // BeginningOfWeek beginning of week
  22. func (now *Now) BeginningOfWeek() time.Time {
  23. t := now.BeginningOfDay()
  24. weekday := int(t.Weekday())
  25. if now.WeekStartDay != time.Sunday {
  26. weekStartDayInt := int(now.WeekStartDay)
  27. if weekday < weekStartDayInt {
  28. weekday = weekday + 7 - weekStartDayInt
  29. } else {
  30. weekday = weekday - weekStartDayInt
  31. }
  32. }
  33. return t.AddDate(0, 0, -weekday)
  34. }
  35. // BeginningOfMonth beginning of month
  36. func (now *Now) BeginningOfMonth() time.Time {
  37. y, m, _ := now.Date()
  38. return time.Date(y, m, 1, 0, 0, 0, 0, now.Location())
  39. }
  40. // BeginningOfQuarter beginning of quarter
  41. func (now *Now) BeginningOfQuarter() time.Time {
  42. month := now.BeginningOfMonth()
  43. offset := (int(month.Month()) - 1) % 3
  44. return month.AddDate(0, -offset, 0)
  45. }
  46. // BeginningOfHalf beginning of half year
  47. func (now *Now) BeginningOfHalf() time.Time {
  48. month := now.BeginningOfMonth()
  49. offset := (int(month.Month()) - 1) % 6
  50. return month.AddDate(0, -offset, 0)
  51. }
  52. // BeginningOfYear BeginningOfYear beginning of year
  53. func (now *Now) BeginningOfYear() time.Time {
  54. y, _, _ := now.Date()
  55. return time.Date(y, time.January, 1, 0, 0, 0, 0, now.Location())
  56. }
  57. // EndOfMinute end of minute
  58. func (now *Now) EndOfMinute() time.Time {
  59. return now.BeginningOfMinute().Add(time.Minute - time.Nanosecond)
  60. }
  61. // EndOfHour end of hour
  62. func (now *Now) EndOfHour() time.Time {
  63. return now.BeginningOfHour().Add(time.Hour - time.Nanosecond)
  64. }
  65. // EndOfDay end of day
  66. func (now *Now) EndOfDay() time.Time {
  67. y, m, d := now.Date()
  68. return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), now.Location())
  69. }
  70. // EndOfWeek end of week
  71. func (now *Now) EndOfWeek() time.Time {
  72. return now.BeginningOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond)
  73. }
  74. // EndOfMonth end of month
  75. func (now *Now) EndOfMonth() time.Time {
  76. return now.BeginningOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond)
  77. }
  78. // EndOfQuarter end of quarter
  79. func (now *Now) EndOfQuarter() time.Time {
  80. return now.BeginningOfQuarter().AddDate(0, 3, 0).Add(-time.Nanosecond)
  81. }
  82. // EndOfHalf end of half year
  83. func (now *Now) EndOfHalf() time.Time {
  84. return now.BeginningOfHalf().AddDate(0, 6, 0).Add(-time.Nanosecond)
  85. }
  86. // EndOfYear end of year
  87. func (now *Now) EndOfYear() time.Time {
  88. return now.BeginningOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond)
  89. }
  90. // Monday monday
  91. /*
  92. func (now *Now) Monday() time.Time {
  93. t := now.BeginningOfDay()
  94. weekday := int(t.Weekday())
  95. if weekday == 0 {
  96. weekday = 7
  97. }
  98. return t.AddDate(0, 0, -weekday+1)
  99. }
  100. */
  101. func (now *Now) Monday(strs ...string) time.Time {
  102. var parseTime time.Time
  103. var err error
  104. if len(strs) > 0 {
  105. parseTime, err = now.Parse(strs...)
  106. if err != nil {
  107. panic(err)
  108. }
  109. } else {
  110. parseTime = now.BeginningOfDay()
  111. }
  112. weekday := int(parseTime.Weekday())
  113. if weekday == 0 {
  114. weekday = 7
  115. }
  116. return parseTime.AddDate(0, 0, -weekday+1)
  117. }
  118. func (now *Now) Sunday(strs ...string) time.Time {
  119. var parseTime time.Time
  120. var err error
  121. if len(strs) > 0 {
  122. parseTime, err = now.Parse(strs...)
  123. if err != nil {
  124. panic(err)
  125. }
  126. } else {
  127. parseTime = now.BeginningOfDay()
  128. }
  129. weekday := int(parseTime.Weekday())
  130. if weekday == 0 {
  131. weekday = 7
  132. }
  133. return parseTime.AddDate(0, 0, (7 - weekday))
  134. }
  135. // EndOfSunday end of sunday
  136. func (now *Now) EndOfSunday() time.Time {
  137. return New(now.Sunday()).EndOfDay()
  138. }
  139. // Quarter returns the yearly quarter
  140. func (now *Now) Quarter() uint {
  141. return (uint(now.Month())-1)/3 + 1
  142. }
  143. func (now *Now) parseWithFormat(str string, location *time.Location) (t time.Time, err error) {
  144. for _, format := range now.TimeFormats {
  145. t, err = time.ParseInLocation(format, str, location)
  146. if err == nil {
  147. return
  148. }
  149. }
  150. err = errors.New("Can't parse string as time: " + str)
  151. return
  152. }
  153. var hasTimeRegexp = regexp.MustCompile(`(\s+|^\s*|T)\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))(\s*$|[Z+-])`) // match 15:04:05, 15:04:05.000, 15:04:05.000000 15, 2017-01-01 15:04, 2021-07-20T00:59:10Z, 2021-07-20T00:59:10+08:00, 2021-07-20T00:00:10-07:00 etc
  154. var onlyTimeRegexp = regexp.MustCompile(`^\s*\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))\s*$`) // match 15:04:05, 15, 15:04:05.000, 15:04:05.000000, etc
  155. // Parse parse string to time
  156. func (now *Now) Parse(strs ...string) (t time.Time, err error) {
  157. var (
  158. setCurrentTime bool
  159. parseTime []int
  160. currentLocation = now.Location()
  161. onlyTimeInStr = true
  162. currentTime = formatTimeToList(now.Time)
  163. )
  164. for _, str := range strs {
  165. hasTimeInStr := hasTimeRegexp.MatchString(str) // match 15:04:05, 15
  166. onlyTimeInStr = hasTimeInStr && onlyTimeInStr && onlyTimeRegexp.MatchString(str)
  167. if t, err = now.parseWithFormat(str, currentLocation); err == nil {
  168. location := t.Location()
  169. parseTime = formatTimeToList(t)
  170. for i, v := range parseTime {
  171. // Don't reset hour, minute, second if current time str including time
  172. if hasTimeInStr && i <= 3 {
  173. continue
  174. }
  175. // If value is zero, replace it with current time
  176. if v == 0 {
  177. if setCurrentTime {
  178. parseTime[i] = currentTime[i]
  179. }
  180. } else {
  181. setCurrentTime = true
  182. }
  183. // if current time only includes time, should change day, month to current time
  184. if onlyTimeInStr {
  185. if i == 4 || i == 5 {
  186. parseTime[i] = currentTime[i]
  187. continue
  188. }
  189. }
  190. }
  191. t = time.Date(parseTime[6], time.Month(parseTime[5]), parseTime[4], parseTime[3], parseTime[2], parseTime[1], parseTime[0], location)
  192. currentTime = formatTimeToList(t)
  193. }
  194. }
  195. return
  196. }
  197. // MustParse must parse string to time or it will panic
  198. func (now *Now) MustParse(strs ...string) (t time.Time) {
  199. t, err := now.Parse(strs...)
  200. if err != nil {
  201. panic(err)
  202. }
  203. return t
  204. }
  205. // Between check time between the begin, end time or not
  206. func (now *Now) Between(begin, end string) bool {
  207. beginTime := now.MustParse(begin)
  208. endTime := now.MustParse(end)
  209. return now.After(beginTime) && now.Before(endTime)
  210. }