gtime_time.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gtime
  7. import (
  8. "bytes"
  9. "strconv"
  10. "time"
  11. )
  12. // Time is a wrapper for time.Time for additional features.
  13. type Time struct {
  14. wrapper
  15. }
  16. // apiUnixNano is an interface definition commonly for custom time.Time wrapper.
  17. type apiUnixNano interface {
  18. UnixNano() int64
  19. }
  20. // New creates and returns a Time object with given parameter.
  21. // The optional parameter can be type of: time.Time/*time.Time, string or integer.
  22. func New(param ...interface{}) *Time {
  23. if len(param) > 0 {
  24. switch r := param[0].(type) {
  25. case time.Time:
  26. return NewFromTime(r)
  27. case *time.Time:
  28. return NewFromTime(*r)
  29. case Time:
  30. return &r
  31. case *Time:
  32. return r
  33. case string:
  34. if len(param) > 1 {
  35. switch t := param[1].(type) {
  36. case string:
  37. return NewFromStrFormat(r, t)
  38. case []byte:
  39. return NewFromStrFormat(r, string(t))
  40. }
  41. }
  42. return NewFromStr(r)
  43. case []byte:
  44. if len(param) > 1 {
  45. switch t := param[1].(type) {
  46. case string:
  47. return NewFromStrFormat(string(r), t)
  48. case []byte:
  49. return NewFromStrFormat(string(r), string(t))
  50. }
  51. }
  52. return NewFromStr(string(r))
  53. case int:
  54. return NewFromTimeStamp(int64(r))
  55. case int64:
  56. return NewFromTimeStamp(r)
  57. default:
  58. if v, ok := r.(apiUnixNano); ok {
  59. return NewFromTimeStamp(v.UnixNano())
  60. }
  61. }
  62. }
  63. return &Time{
  64. wrapper{time.Time{}},
  65. }
  66. }
  67. // Now creates and returns a time object of now.
  68. func Now() *Time {
  69. return &Time{
  70. wrapper{time.Now()},
  71. }
  72. }
  73. // NewFromTime creates and returns a Time object with given time.Time object.
  74. func NewFromTime(t time.Time) *Time {
  75. return &Time{
  76. wrapper{t},
  77. }
  78. }
  79. // NewFromStr creates and returns a Time object with given string.
  80. // Note that it returns nil if there's error occurs.
  81. func NewFromStr(str string) *Time {
  82. if t, err := StrToTime(str); err == nil {
  83. return t
  84. }
  85. return nil
  86. }
  87. // NewFromStrFormat creates and returns a Time object with given string and
  88. // custom format like: Y-m-d H:i:s.
  89. // Note that it returns nil if there's error occurs.
  90. func NewFromStrFormat(str string, format string) *Time {
  91. if t, err := StrToTimeFormat(str, format); err == nil {
  92. return t
  93. }
  94. return nil
  95. }
  96. // NewFromStrLayout creates and returns a Time object with given string and
  97. // stdlib layout like: 2006-01-02 15:04:05.
  98. // Note that it returns nil if there's error occurs.
  99. func NewFromStrLayout(str string, layout string) *Time {
  100. if t, err := StrToTimeLayout(str, layout); err == nil {
  101. return t
  102. }
  103. return nil
  104. }
  105. // NewFromTimeStamp creates and returns a Time object with given timestamp,
  106. // which can be in seconds to nanoseconds.
  107. // Eg: 1600443866 and 1600443866199266000 are both considered as valid timestamp number.
  108. func NewFromTimeStamp(timestamp int64) *Time {
  109. if timestamp == 0 {
  110. return &Time{}
  111. }
  112. var sec, nano int64
  113. if timestamp > 1e9 {
  114. for timestamp < 1e18 {
  115. timestamp *= 10
  116. }
  117. sec = timestamp / 1e9
  118. nano = timestamp % 1e9
  119. } else {
  120. sec = timestamp
  121. }
  122. return &Time{
  123. wrapper{time.Unix(sec, nano)},
  124. }
  125. }
  126. // Timestamp returns the timestamp in seconds.
  127. func (t *Time) Timestamp() int64 {
  128. return t.UnixNano() / 1e9
  129. }
  130. // TimestampMilli returns the timestamp in milliseconds.
  131. func (t *Time) TimestampMilli() int64 {
  132. return t.UnixNano() / 1e6
  133. }
  134. // TimestampMicro returns the timestamp in microseconds.
  135. func (t *Time) TimestampMicro() int64 {
  136. return t.UnixNano() / 1e3
  137. }
  138. // TimestampNano returns the timestamp in nanoseconds.
  139. func (t *Time) TimestampNano() int64 {
  140. return t.UnixNano()
  141. }
  142. // TimestampStr is a convenience method which retrieves and returns
  143. // the timestamp in seconds as string.
  144. func (t *Time) TimestampStr() string {
  145. return strconv.FormatInt(t.Timestamp(), 10)
  146. }
  147. // TimestampMilliStr is a convenience method which retrieves and returns
  148. // the timestamp in milliseconds as string.
  149. func (t *Time) TimestampMilliStr() string {
  150. return strconv.FormatInt(t.TimestampMilli(), 10)
  151. }
  152. // TimestampMicroStr is a convenience method which retrieves and returns
  153. // the timestamp in microseconds as string.
  154. func (t *Time) TimestampMicroStr() string {
  155. return strconv.FormatInt(t.TimestampMicro(), 10)
  156. }
  157. // TimestampNanoStr is a convenience method which retrieves and returns
  158. // the timestamp in nanoseconds as string.
  159. func (t *Time) TimestampNanoStr() string {
  160. return strconv.FormatInt(t.TimestampNano(), 10)
  161. }
  162. // Month returns the month of the year specified by t.
  163. func (t *Time) Month() int {
  164. return int(t.Time.Month())
  165. }
  166. // Second returns the second offset within the minute specified by t,
  167. // in the range [0, 59].
  168. func (t *Time) Second() int {
  169. return t.Time.Second()
  170. }
  171. // Millisecond returns the millisecond offset within the second specified by t,
  172. // in the range [0, 999].
  173. func (t *Time) Millisecond() int {
  174. return t.Time.Nanosecond() / 1e6
  175. }
  176. // Microsecond returns the microsecond offset within the second specified by t,
  177. // in the range [0, 999999].
  178. func (t *Time) Microsecond() int {
  179. return t.Time.Nanosecond() / 1e3
  180. }
  181. // Nanosecond returns the nanosecond offset within the second specified by t,
  182. // in the range [0, 999999999].
  183. func (t *Time) Nanosecond() int {
  184. return t.Time.Nanosecond()
  185. }
  186. // String returns current time object as string.
  187. func (t *Time) String() string {
  188. if t == nil {
  189. return ""
  190. }
  191. if t.IsZero() {
  192. return ""
  193. }
  194. return t.Format("Y-m-d H:i:s")
  195. }
  196. // Clone returns a new Time object which is a clone of current time object.
  197. func (t *Time) Clone() *Time {
  198. return New(t.Time)
  199. }
  200. // Add adds the duration to current time.
  201. func (t *Time) Add(d time.Duration) *Time {
  202. newTime := t.Clone()
  203. newTime.Time = newTime.Time.Add(d)
  204. return newTime
  205. }
  206. // AddStr parses the given duration as string and adds it to current time.
  207. func (t *Time) AddStr(duration string) (*Time, error) {
  208. if d, err := time.ParseDuration(duration); err != nil {
  209. return nil, err
  210. } else {
  211. return t.Add(d), nil
  212. }
  213. }
  214. // UTC converts current time to UTC timezone.
  215. func (t *Time) UTC() *Time {
  216. newTime := t.Clone()
  217. newTime.Time = newTime.Time.UTC()
  218. return newTime
  219. }
  220. // ISO8601 formats the time as ISO8601 and returns it as string.
  221. func (t *Time) ISO8601() string {
  222. return t.Layout("2006-01-02T15:04:05-07:00")
  223. }
  224. // RFC822 formats the time as RFC822 and returns it as string.
  225. func (t *Time) RFC822() string {
  226. return t.Layout("Mon, 02 Jan 06 15:04 MST")
  227. }
  228. // AddDate adds year, month and day to the time.
  229. func (t *Time) AddDate(years int, months int, days int) *Time {
  230. newTime := t.Clone()
  231. newTime.Time = newTime.Time.AddDate(years, months, days)
  232. return newTime
  233. }
  234. // Round returns the result of rounding t to the nearest multiple of d (since the zero time).
  235. // The rounding behavior for halfway values is to round up.
  236. // If d <= 0, Round returns t stripped of any monotonic clock reading but otherwise unchanged.
  237. //
  238. // Round operates on the time as an absolute duration since the
  239. // zero time; it does not operate on the presentation form of the
  240. // time. Thus, Round(Hour) may return a time with a non-zero
  241. // minute, depending on the time's Location.
  242. func (t *Time) Round(d time.Duration) *Time {
  243. newTime := t.Clone()
  244. newTime.Time = newTime.Time.Round(d)
  245. return newTime
  246. }
  247. // Truncate returns the result of rounding t down to a multiple of d (since the zero time).
  248. // If d <= 0, Truncate returns t stripped of any monotonic clock reading but otherwise unchanged.
  249. //
  250. // Truncate operates on the time as an absolute duration since the
  251. // zero time; it does not operate on the presentation form of the
  252. // time. Thus, Truncate(Hour) may return a time with a non-zero
  253. // minute, depending on the time's Location.
  254. func (t *Time) Truncate(d time.Duration) *Time {
  255. newTime := t.Clone()
  256. newTime.Time = newTime.Time.Truncate(d)
  257. return newTime
  258. }
  259. // Equal reports whether t and u represent the same time instant.
  260. // Two times can be equal even if they are in different locations.
  261. // For example, 6:00 +0200 CEST and 4:00 UTC are Equal.
  262. // See the documentation on the Time type for the pitfalls of using == with
  263. // Time values; most code should use Equal instead.
  264. func (t *Time) Equal(u *Time) bool {
  265. return t.Time.Equal(u.Time)
  266. }
  267. // Before reports whether the time instant t is before u.
  268. func (t *Time) Before(u *Time) bool {
  269. return t.Time.Before(u.Time)
  270. }
  271. // After reports whether the time instant t is after u.
  272. func (t *Time) After(u *Time) bool {
  273. return t.Time.After(u.Time)
  274. }
  275. // Sub returns the duration t-u. If the result exceeds the maximum (or minimum)
  276. // value that can be stored in a Duration, the maximum (or minimum) duration
  277. // will be returned.
  278. // To compute t-d for a duration d, use t.Add(-d).
  279. func (t *Time) Sub(u *Time) time.Duration {
  280. return t.Time.Sub(u.Time)
  281. }
  282. // MarshalJSON implements the interface MarshalJSON for json.Marshal.
  283. func (t *Time) MarshalJSON() ([]byte, error) {
  284. return []byte(`"` + t.String() + `"`), nil
  285. }
  286. // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
  287. func (t *Time) UnmarshalJSON(b []byte) error {
  288. if len(b) == 0 {
  289. t.Time = time.Time{}
  290. return nil
  291. }
  292. newTime, err := StrToTime(string(bytes.Trim(b, `"`)))
  293. if err != nil {
  294. return err
  295. }
  296. t.Time = newTime.Time
  297. return nil
  298. }