github.com/gogf/gf@v1.16.9/os/gtime/gtime_time.go (about) 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 7 package gtime 8 9 import ( 10 "bytes" 11 "github.com/gogf/gf/errors/gcode" 12 "github.com/gogf/gf/errors/gerror" 13 "strconv" 14 "time" 15 ) 16 17 // Time is a wrapper for time.Time for additional features. 18 type Time struct { 19 wrapper 20 } 21 22 // apiUnixNano is an interface definition commonly for custom time.Time wrapper. 23 type apiUnixNano interface { 24 UnixNano() int64 25 } 26 27 // New creates and returns a Time object with given parameter. 28 // The optional parameter can be type of: time.Time/*time.Time, string or integer. 29 func New(param ...interface{}) *Time { 30 if len(param) > 0 { 31 switch r := param[0].(type) { 32 case time.Time: 33 return NewFromTime(r) 34 case *time.Time: 35 return NewFromTime(*r) 36 37 case Time: 38 return &r 39 40 case *Time: 41 return r 42 43 case string: 44 if len(param) > 1 { 45 switch t := param[1].(type) { 46 case string: 47 return NewFromStrFormat(r, t) 48 case []byte: 49 return NewFromStrFormat(r, string(t)) 50 } 51 } 52 return NewFromStr(r) 53 54 case []byte: 55 if len(param) > 1 { 56 switch t := param[1].(type) { 57 case string: 58 return NewFromStrFormat(string(r), t) 59 case []byte: 60 return NewFromStrFormat(string(r), string(t)) 61 } 62 } 63 return NewFromStr(string(r)) 64 65 case int: 66 return NewFromTimeStamp(int64(r)) 67 68 case int64: 69 return NewFromTimeStamp(r) 70 71 default: 72 if v, ok := r.(apiUnixNano); ok { 73 return NewFromTimeStamp(v.UnixNano()) 74 } 75 } 76 } 77 return &Time{ 78 wrapper{time.Time{}}, 79 } 80 } 81 82 // Now creates and returns a time object of now. 83 func Now() *Time { 84 return &Time{ 85 wrapper{time.Now()}, 86 } 87 } 88 89 // NewFromTime creates and returns a Time object with given time.Time object. 90 func NewFromTime(t time.Time) *Time { 91 return &Time{ 92 wrapper{t}, 93 } 94 } 95 96 // NewFromStr creates and returns a Time object with given string. 97 // Note that it returns nil if there's error occurs. 98 func NewFromStr(str string) *Time { 99 if t, err := StrToTime(str); err == nil { 100 return t 101 } 102 return nil 103 } 104 105 // NewFromStrFormat creates and returns a Time object with given string and 106 // custom format like: Y-m-d H:i:s. 107 // Note that it returns nil if there's error occurs. 108 func NewFromStrFormat(str string, format string) *Time { 109 if t, err := StrToTimeFormat(str, format); err == nil { 110 return t 111 } 112 return nil 113 } 114 115 // NewFromStrLayout creates and returns a Time object with given string and 116 // stdlib layout like: 2006-01-02 15:04:05. 117 // Note that it returns nil if there's error occurs. 118 func NewFromStrLayout(str string, layout string) *Time { 119 if t, err := StrToTimeLayout(str, layout); err == nil { 120 return t 121 } 122 return nil 123 } 124 125 // NewFromTimeStamp creates and returns a Time object with given timestamp, 126 // which can be in seconds to nanoseconds. 127 // Eg: 1600443866 and 1600443866199266000 are both considered as valid timestamp number. 128 func NewFromTimeStamp(timestamp int64) *Time { 129 if timestamp == 0 { 130 return &Time{} 131 } 132 var sec, nano int64 133 if timestamp > 1e9 { 134 for timestamp < 1e18 { 135 timestamp *= 10 136 } 137 sec = timestamp / 1e9 138 nano = timestamp % 1e9 139 } else { 140 sec = timestamp 141 } 142 return &Time{ 143 wrapper{time.Unix(sec, nano)}, 144 } 145 } 146 147 // Timestamp returns the timestamp in seconds. 148 func (t *Time) Timestamp() int64 { 149 return t.UnixNano() / 1e9 150 } 151 152 // TimestampMilli returns the timestamp in milliseconds. 153 func (t *Time) TimestampMilli() int64 { 154 return t.UnixNano() / 1e6 155 } 156 157 // TimestampMicro returns the timestamp in microseconds. 158 func (t *Time) TimestampMicro() int64 { 159 return t.UnixNano() / 1e3 160 } 161 162 // TimestampNano returns the timestamp in nanoseconds. 163 func (t *Time) TimestampNano() int64 { 164 return t.UnixNano() 165 } 166 167 // TimestampStr is a convenience method which retrieves and returns 168 // the timestamp in seconds as string. 169 func (t *Time) TimestampStr() string { 170 return strconv.FormatInt(t.Timestamp(), 10) 171 } 172 173 // TimestampMilliStr is a convenience method which retrieves and returns 174 // the timestamp in milliseconds as string. 175 func (t *Time) TimestampMilliStr() string { 176 return strconv.FormatInt(t.TimestampMilli(), 10) 177 } 178 179 // TimestampMicroStr is a convenience method which retrieves and returns 180 // the timestamp in microseconds as string. 181 func (t *Time) TimestampMicroStr() string { 182 return strconv.FormatInt(t.TimestampMicro(), 10) 183 } 184 185 // TimestampNanoStr is a convenience method which retrieves and returns 186 // the timestamp in nanoseconds as string. 187 func (t *Time) TimestampNanoStr() string { 188 return strconv.FormatInt(t.TimestampNano(), 10) 189 } 190 191 // Month returns the month of the year specified by t. 192 func (t *Time) Month() int { 193 return int(t.Time.Month()) 194 } 195 196 // Second returns the second offset within the minute specified by t, 197 // in the range [0, 59]. 198 func (t *Time) Second() int { 199 return t.Time.Second() 200 } 201 202 // Millisecond returns the millisecond offset within the second specified by t, 203 // in the range [0, 999]. 204 func (t *Time) Millisecond() int { 205 return t.Time.Nanosecond() / 1e6 206 } 207 208 // Microsecond returns the microsecond offset within the second specified by t, 209 // in the range [0, 999999]. 210 func (t *Time) Microsecond() int { 211 return t.Time.Nanosecond() / 1e3 212 } 213 214 // Nanosecond returns the nanosecond offset within the second specified by t, 215 // in the range [0, 999999999]. 216 func (t *Time) Nanosecond() int { 217 return t.Time.Nanosecond() 218 } 219 220 // String returns current time object as string. 221 func (t *Time) String() string { 222 if t == nil { 223 return "" 224 } 225 if t.IsZero() { 226 return "" 227 } 228 return t.Format("Y-m-d H:i:s") 229 } 230 231 // IsZero reports whether t represents the zero time instant, 232 // January 1, year 1, 00:00:00 UTC. 233 func (t *Time) IsZero() bool { 234 if t == nil { 235 return true 236 } 237 return t.Time.IsZero() 238 } 239 240 // Clone returns a new Time object which is a clone of current time object. 241 func (t *Time) Clone() *Time { 242 return New(t.Time) 243 } 244 245 // Add adds the duration to current time. 246 func (t *Time) Add(d time.Duration) *Time { 247 newTime := t.Clone() 248 newTime.Time = newTime.Time.Add(d) 249 return newTime 250 } 251 252 // AddStr parses the given duration as string and adds it to current time. 253 func (t *Time) AddStr(duration string) (*Time, error) { 254 if d, err := time.ParseDuration(duration); err != nil { 255 return nil, err 256 } else { 257 return t.Add(d), nil 258 } 259 } 260 261 // UTC converts current time to UTC timezone. 262 func (t *Time) UTC() *Time { 263 newTime := t.Clone() 264 newTime.Time = newTime.Time.UTC() 265 return newTime 266 } 267 268 // ISO8601 formats the time as ISO8601 and returns it as string. 269 func (t *Time) ISO8601() string { 270 return t.Layout("2006-01-02T15:04:05-07:00") 271 } 272 273 // RFC822 formats the time as RFC822 and returns it as string. 274 func (t *Time) RFC822() string { 275 return t.Layout("Mon, 02 Jan 06 15:04 MST") 276 } 277 278 // AddDate adds year, month and day to the time. 279 func (t *Time) AddDate(years int, months int, days int) *Time { 280 newTime := t.Clone() 281 newTime.Time = newTime.Time.AddDate(years, months, days) 282 return newTime 283 } 284 285 // Round returns the result of rounding t to the nearest multiple of d (since the zero time). 286 // The rounding behavior for halfway values is to round up. 287 // If d <= 0, Round returns t stripped of any monotonic clock reading but otherwise unchanged. 288 // 289 // Round operates on the time as an absolute duration since the 290 // zero time; it does not operate on the presentation form of the 291 // time. Thus, Round(Hour) may return a time with a non-zero 292 // minute, depending on the time's Location. 293 func (t *Time) Round(d time.Duration) *Time { 294 newTime := t.Clone() 295 newTime.Time = newTime.Time.Round(d) 296 return newTime 297 } 298 299 // Truncate returns the result of rounding t down to a multiple of d (since the zero time). 300 // If d <= 0, Truncate returns t stripped of any monotonic clock reading but otherwise unchanged. 301 // 302 // Truncate operates on the time as an absolute duration since the 303 // zero time; it does not operate on the presentation form of the 304 // time. Thus, Truncate(Hour) may return a time with a non-zero 305 // minute, depending on the time's Location. 306 func (t *Time) Truncate(d time.Duration) *Time { 307 newTime := t.Clone() 308 newTime.Time = newTime.Time.Truncate(d) 309 return newTime 310 } 311 312 // Equal reports whether t and u represent the same time instant. 313 // Two times can be equal even if they are in different locations. 314 // For example, 6:00 +0200 CEST and 4:00 UTC are Equal. 315 // See the documentation on the Time type for the pitfalls of using == with 316 // Time values; most code should use Equal instead. 317 func (t *Time) Equal(u *Time) bool { 318 return t.Time.Equal(u.Time) 319 } 320 321 // Before reports whether the time instant t is before u. 322 func (t *Time) Before(u *Time) bool { 323 return t.Time.Before(u.Time) 324 } 325 326 // After reports whether the time instant t is after u. 327 func (t *Time) After(u *Time) bool { 328 return t.Time.After(u.Time) 329 } 330 331 // Sub returns the duration t-u. If the result exceeds the maximum (or minimum) 332 // value that can be stored in a Duration, the maximum (or minimum) duration 333 // will be returned. 334 // To compute t-d for a duration d, use t.Add(-d). 335 func (t *Time) Sub(u *Time) time.Duration { 336 return t.Time.Sub(u.Time) 337 } 338 339 // StartOfMinute clones and returns a new time of which the seconds is set to 0. 340 func (t *Time) StartOfMinute() *Time { 341 newTime := t.Clone() 342 newTime.Time = newTime.Time.Truncate(time.Minute) 343 return newTime 344 } 345 346 // StartOfHour clones and returns a new time of which the hour, minutes and seconds are set to 0. 347 func (t *Time) StartOfHour() *Time { 348 y, m, d := t.Date() 349 newTime := t.Clone() 350 newTime.Time = time.Date(y, m, d, newTime.Time.Hour(), 0, 0, 0, newTime.Time.Location()) 351 return newTime 352 } 353 354 // StartOfDay clones and returns a new time which is the start of day, its time is set to 00:00:00. 355 func (t *Time) StartOfDay() *Time { 356 y, m, d := t.Date() 357 newTime := t.Clone() 358 newTime.Time = time.Date(y, m, d, 0, 0, 0, 0, newTime.Time.Location()) 359 return newTime 360 } 361 362 // StartOfWeek clones and returns a new time which is the first day of week and its time is set to 363 // 00:00:00. 364 func (t *Time) StartOfWeek() *Time { 365 weekday := int(t.Weekday()) 366 return t.StartOfDay().AddDate(0, 0, -weekday) 367 } 368 369 // StartOfMonth clones and returns a new time which is the first day of the month and its is set to 370 // 00:00:00 371 func (t *Time) StartOfMonth() *Time { 372 y, m, _ := t.Date() 373 newTime := t.Clone() 374 newTime.Time = time.Date(y, m, 1, 0, 0, 0, 0, newTime.Time.Location()) 375 return newTime 376 } 377 378 // StartOfQuarter clones and returns a new time which is the first day of the quarter and its time is set 379 // to 00:00:00. 380 func (t *Time) StartOfQuarter() *Time { 381 month := t.StartOfMonth() 382 offset := (int(month.Month()) - 1) % 3 383 return month.AddDate(0, -offset, 0) 384 } 385 386 // StartOfHalf clones and returns a new time which is the first day of the half year and its time is set 387 // to 00:00:00. 388 func (t *Time) StartOfHalf() *Time { 389 month := t.StartOfMonth() 390 offset := (int(month.Month()) - 1) % 6 391 return month.AddDate(0, -offset, 0) 392 } 393 394 // StartOfYear clones and returns a new time which is the first day of the year and its time is set to 395 // 00:00:00. 396 func (t *Time) StartOfYear() *Time { 397 y, _, _ := t.Date() 398 newTime := t.Clone() 399 newTime.Time = time.Date(y, time.January, 1, 0, 0, 0, 0, newTime.Time.Location()) 400 return newTime 401 } 402 403 // EndOfMinute clones and returns a new time of which the seconds is set to 59. 404 func (t *Time) EndOfMinute() *Time { 405 return t.StartOfMinute().Add(time.Minute - time.Nanosecond) 406 } 407 408 // EndOfHour clones and returns a new time of which the minutes and seconds are both set to 59. 409 func (t *Time) EndOfHour() *Time { 410 return t.StartOfHour().Add(time.Hour - time.Nanosecond) 411 } 412 413 // EndOfDay clones and returns a new time which is the end of day the and its time is set to 23:59:59. 414 func (t *Time) EndOfDay() *Time { 415 y, m, d := t.Date() 416 newTime := t.Clone() 417 newTime.Time = time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), newTime.Time.Location()) 418 return newTime 419 } 420 421 // EndOfWeek clones and returns a new time which is the end of week and its time is set to 23:59:59. 422 func (t *Time) EndOfWeek() *Time { 423 return t.StartOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond) 424 } 425 426 // EndOfMonth clones and returns a new time which is the end of the month and its time is set to 23:59:59. 427 func (t *Time) EndOfMonth() *Time { 428 return t.StartOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond) 429 } 430 431 // EndOfQuarter clones and returns a new time which is end of the quarter and its time is set to 23:59:59. 432 func (t *Time) EndOfQuarter() *Time { 433 return t.StartOfQuarter().AddDate(0, 3, 0).Add(-time.Nanosecond) 434 } 435 436 // EndOfHalf clones and returns a new time which is the end of the half year and its time is set to 23:59:59. 437 func (t *Time) EndOfHalf() *Time { 438 return t.StartOfHalf().AddDate(0, 6, 0).Add(-time.Nanosecond) 439 } 440 441 // EndOfYear clones and returns a new time which is the end of the year and its time is set to 23:59:59. 442 func (t *Time) EndOfYear() *Time { 443 return t.StartOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond) 444 } 445 446 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 447 func (t *Time) MarshalJSON() ([]byte, error) { 448 return []byte(`"` + t.String() + `"`), nil 449 } 450 451 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 452 func (t *Time) UnmarshalJSON(b []byte) error { 453 if len(b) == 0 { 454 t.Time = time.Time{} 455 return nil 456 } 457 newTime, err := StrToTime(string(bytes.Trim(b, `"`))) 458 if err != nil { 459 return err 460 } 461 t.Time = newTime.Time 462 return nil 463 } 464 465 // UnmarshalText implements the encoding.TextUnmarshaler interface. 466 // Note that it overwrites the same implementer of `time.Time`. 467 func (t *Time) UnmarshalText(data []byte) error { 468 vTime := New(data) 469 if vTime != nil { 470 *t = *vTime 471 return nil 472 } 473 return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid time value: %s`, data) 474 } 475 476 // NoValidation marks this struct object will not be validated by package gvalid. 477 func (t *Time) NoValidation() { 478 479 }