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  }