github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/time_stamp.go (about)

     1  package f
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  	"time"
     8  )
     9  
    10  var (
    11  	ZoneName         string
    12  	ZoneOffset       int
    13  	ZoneOffsetSecond time.Duration
    14  )
    15  
    16  func init() {
    17  	ZoneName, ZoneOffset = time.Now().Zone()
    18  	ZoneOffsetSecond = time.Duration(ZoneOffset) * time.Second
    19  }
    20  
    21  // TimeStamp a time stamp and extended methods.
    22  type TimeStamp struct {
    23  	time.Time
    24  	UnixSecond     int64
    25  	UnixNanoSecond int64
    26  }
    27  
    28  // UnixSecondTimeStampString 时间戳 unix time stamp,
    29  // 精确到秒 10位数: 1582950407
    30  // the number of seconds elapsed since January 1, 1970 UTC. The result does not depend on the
    31  // location associated with t.
    32  func (t *TimeStamp) UnixSecondTimeStampString() string {
    33  	return strconv.FormatInt(t.UnixSecond, 10)
    34  }
    35  
    36  // MilliSecondTimeStampString 时间戳 unix time stamp,
    37  // 精确到毫秒 13位数: 1582950407018
    38  // the number of milliseconds elapsed since January 1, 1970 UTC. The result does not depend on the
    39  // location associated with t.
    40  func (t *TimeStamp) MilliSecondTimeStampString() string {
    41  	return t.UnixSecondTimeStampString() + fmt.Sprintf("%03d", t.Time.Nanosecond()/1e6)
    42  }
    43  
    44  func (t *TimeStamp) MilliSecondTimeStamp() int64 {
    45  	return t.UnixNanoSecond / 1e6
    46  }
    47  
    48  // MicroSecondTimeStampString 时间戳 unix time stamp,
    49  // 精确到微秒 16位数: 1582950407018018
    50  // the number of microseconds elapsed since January 1, 1970 UTC. The result does not depend on the
    51  // location associated with t.
    52  func (t *TimeStamp) MicroSecondTimeStampString() string {
    53  	return t.UnixSecondTimeStampString() + fmt.Sprintf("%06d", t.Time.Nanosecond()/1e3)
    54  }
    55  
    56  func (t *TimeStamp) MicroSecondTimeStamp() int64 {
    57  	return t.UnixNanoSecond / 1e3
    58  }
    59  
    60  // NanoSecondTimeStampString 时间戳 unix time stamp,
    61  // 精确到纳秒 19位数: 1582950407018018100
    62  // the number of nanoseconds elapsed since January 1, 1970 UTC. The result does not depend on the
    63  // location associated with t.
    64  func (t *TimeStamp) NanoSecondTimeStampString() string {
    65  	return t.UnixSecondTimeStampString() + fmt.Sprintf("%09d", t.Time.Nanosecond())
    66  }
    67  
    68  // Now get now timestamp in Local time.
    69  // upToSecond is used to remove milliseconds.
    70  func Now(upToSecond ...bool) *TimeStamp {
    71  	return TimeFrom(time.Now(), upToSecond...)
    72  }
    73  
    74  // NowLocalString get a time at now.
    75  func NowLocalString(upToSecond ...bool) string {
    76  	return Now(upToSecond...).LocalString()
    77  }
    78  
    79  // TimeFrom get a timestamp in Local time.
    80  // upToSecond is used to remove milliseconds.
    81  func TimeFrom(t time.Time, upToSecond ...bool) *TimeStamp {
    82  	ts := &TimeStamp{t, t.Unix(), 0}
    83  	if len(upToSecond) > 0 && upToSecond[0] == true {
    84  		ts.Time = time.Unix(ts.UnixSecond, 0).Local()
    85  		ts.UnixNanoSecond = ts.UnixSecond * 1e9
    86  	} else {
    87  		ts.UnixNanoSecond = t.UnixNano()
    88  	}
    89  	return ts
    90  }
    91  
    92  // TimeFromLocalString get a timestamp in Time string layouts.
    93  func TimeFromLocalString(s string, layouts ...string) (*TimeStamp, error) {
    94  	if t, err := ToUTCTime(s, layouts...); err != nil {
    95  		return nil, err
    96  	} else {
    97  		t = t.Local()
    98  		return &TimeStamp{t, t.Unix(), t.UnixNano()}, nil
    99  	}
   100  }
   101  
   102  // TimeFromUTCString get a timestamp in Time string layouts.
   103  func TimeFromUTCString(s string, layouts ...string) (*TimeStamp, error) {
   104  	if t, err := ToTime(s, layouts...); err != nil {
   105  		return nil, err
   106  	} else {
   107  		t = t.Local()
   108  		return &TimeStamp{t, t.Unix(), t.UnixNano()}, nil
   109  	}
   110  }
   111  
   112  // TimeFrom get a timestamp in Time bytes.
   113  func TimeFromBytes(data []byte) (*TimeStamp, error) {
   114  	t := time.Time{}
   115  	if err := t.UnmarshalBinary(data); err != nil {
   116  		return nil, err
   117  	}
   118  	ts := &TimeStamp{t, t.Unix(), t.UnixNano()}
   119  	return ts, nil
   120  }
   121  
   122  // NewTimeStamp convert a timestamp to Local time.
   123  // the timestamp length equals(10/13/16/19) since January 1, 1970 UTC.
   124  func NewTimeStamp(i int64) *TimeStamp {
   125  	t, _ := time.Parse(DateTimeFormatString, "1970-01-01 00:00:00")
   126  	if i < 1e12 {
   127  		t = t.Add(time.Duration(i) * time.Second)
   128  	} else if i < 1e15 {
   129  		t = t.Add(time.Duration(i/1e3) * time.Second).Add(time.Duration(i%1e3) * time.Millisecond)
   130  	} else if i < 1e18 {
   131  		t = t.Add(time.Duration(i/1e6) * time.Second).Add(time.Duration(i%1e6) * time.Microsecond)
   132  	} else {
   133  		t = t.Add(time.Duration(i/1e9) * time.Second).Add(time.Duration(i%1e9) * time.Nanosecond)
   134  	}
   135  	t = t.Local()
   136  	ts := &TimeStamp{t, t.Unix(), t.UnixNano()}
   137  	return ts
   138  }
   139  
   140  // TimeStampFrom get a timestamp in Local time.
   141  // the timestamp length equals(10/13/16/19) since January 1, 1970 UTC.
   142  func TimeStampFrom(timestamp string) *TimeStamp {
   143  	if len(timestamp) < 10 {
   144  		return nil
   145  	}
   146  	seconds, err := strconv.ParseInt(timestamp[0:10], 10, 64)
   147  	if err != nil {
   148  		return nil
   149  	}
   150  	nanoSeconds := 0
   151  	switch n := timestamp[10:]; len(n) {
   152  	case 3:
   153  		if i, err := strconv.Atoi(n); err != nil {
   154  			return nil
   155  		} else {
   156  			nanoSeconds = i * 1e6
   157  		}
   158  	case 6:
   159  		if i, err := strconv.Atoi(n); err != nil {
   160  			return nil
   161  		} else {
   162  			nanoSeconds = i * 1e3
   163  		}
   164  	case 9:
   165  		if i, err := strconv.Atoi(n); err != nil {
   166  			return nil
   167  		} else {
   168  			nanoSeconds = i
   169  		}
   170  	default:
   171  		return nil
   172  	}
   173  	return TimeStampFromSeconds(seconds, int64(nanoSeconds))
   174  }
   175  
   176  // TimeStampFromSeconds get a timestamp in Local time.
   177  // the number of seconds and nanoSeconds since January 1, 1970 UTC.
   178  func TimeStampFromSeconds(seconds int64, nanoSeconds int64) *TimeStamp {
   179  	t := time.Unix(seconds, nanoSeconds).Local()
   180  	ts := &TimeStamp{t, t.Unix(), t.UnixNano()}
   181  	return ts
   182  }
   183  
   184  // UTCTimeStampString get UTC time string,
   185  // 精确到毫秒 17位数: 20200202042647003
   186  // 或精确到秒 14位数: 20200202042647 (upToSecond=true)
   187  func (t *TimeStamp) UTCTimeStampString(upToSecond ...bool) string {
   188  	if len(upToSecond) > 0 && upToSecond[0] == true {
   189  		return t.AsUTCTime().Format(TimeFormatStringS)
   190  	}
   191  	s := t.AsUTCTime().Format(TimeFormatStringM)
   192  	return strings.Replace(s, ".", "", 1)
   193  }
   194  
   195  // LocalTimeStampString get Local time string,
   196  // 精确到毫秒 17位数: 20200202122647003
   197  // 或精确到秒 14位数: 20200202042647 (upToSecond=true)
   198  func (t *TimeStamp) LocalTimeStampString(upToSecond ...bool) string {
   199  	if len(upToSecond) > 0 && upToSecond[0] == true {
   200  		return t.Time.Format(TimeFormatStringS)
   201  	}
   202  	s := t.Time.Format(TimeFormatStringM)
   203  	return strings.Replace(s, ".", "", 1)
   204  }
   205  
   206  // UTCString get UTC time string,
   207  // 精确到秒: 2020-02-02 04:26:47  the time of second.
   208  func (t *TimeStamp) UTCString(layouts ...string) string {
   209  	layout := DateTimeFormatString
   210  	if len(layouts) > 0 {
   211  		layout = layouts[0]
   212  	}
   213  	if name, _ := t.Time.Zone(); name == ZoneName {
   214  		return toUTCTime(t.Time).Format(layout)
   215  	}
   216  	return t.AsUTCTime().Format(layout)
   217  }
   218  
   219  // LocalString get Local time string,
   220  // 精确到秒: 2020-02-02 12:26:47  the time of second.
   221  func (t *TimeStamp) LocalString(layouts ...string) string {
   222  	layout := DateTimeFormatString
   223  	if len(layouts) > 0 {
   224  		layout = layouts[0]
   225  	}
   226  	if name, _ := t.Time.Zone(); name != ZoneName {
   227  		return toLocalTime(t.Time).Format(layout)
   228  	}
   229  	return t.Time.Format(layout)
   230  }
   231  
   232  // UTCTimeString get UTC time string,
   233  // 精确到毫秒: 2020-02-02 04:26:47.003  the time of millisecond.
   234  func (t *TimeStamp) UTCTimeString(layouts ...string) string {
   235  	layout := TimeFormatString
   236  	if len(layouts) > 0 {
   237  		layout = layouts[0]
   238  	}
   239  	if name, _ := t.Time.Zone(); name == ZoneName {
   240  		return toUTCTime(t.Time).Format(layout)
   241  	}
   242  	return t.AsUTCTime().Format(layout)
   243  }
   244  
   245  // LocalTimeString get Local time string,
   246  // 精确到毫秒: 2020-02-02 12:26:47.003  the time of millisecond.
   247  func (t *TimeStamp) LocalTimeString(layouts ...string) string {
   248  	layout := TimeFormatString
   249  	if len(layouts) > 0 {
   250  		layout = layouts[0]
   251  	}
   252  	if name, _ := t.Time.Zone(); name != ZoneName {
   253  		return toLocalTime(t.Time).Format(layout)
   254  	}
   255  	return t.Time.Format(layout)
   256  }
   257  
   258  // UTCDateString get UTC date string,
   259  // 精确到天: 2020-02-02  the date.
   260  func (t *TimeStamp) UTCDateString(layouts ...string) string {
   261  	layout := DateFormatString
   262  	if len(layouts) > 0 {
   263  		layout = layouts[0]
   264  	}
   265  	return t.AsUTCTime().Format(layout)
   266  }
   267  
   268  // LocalDateString get Local date string,
   269  // 精确到天: 2020-02-02  the date.
   270  func (t *TimeStamp) LocalDateString(layouts ...string) string {
   271  	layout := DateFormatString
   272  	if len(layouts) > 0 {
   273  		layout = layouts[0]
   274  	}
   275  	return t.Time.Format(layout)
   276  }
   277  
   278  // AsTime get a time in Local locale.
   279  func (t *TimeStamp) AsTime() time.Time {
   280  	return t.Time
   281  }
   282  
   283  // AsTimeIn Convert timestamp as time in a locale, equals t.In(local).
   284  func (t *TimeStamp) AsTimeIn(local *time.Location) time.Time {
   285  	return time.Unix(t.UnixSecond, int64(t.Nanosecond())).In(local)
   286  }
   287  
   288  // AsLocal Convert timestamp as time for Local locale.
   289  func (t *TimeStamp) AsLocal() *TimeStamp {
   290  	t.Time = toLocalTime(t.Time)
   291  	return t
   292  }
   293  
   294  // AsLocalTime Convert timestamp as time for Local locale.
   295  func (t *TimeStamp) AsLocalTime() time.Time {
   296  	return t.Time.Local()
   297  }
   298  
   299  // AsUTC Convert timestamp as time for UTC locale.
   300  func (t *TimeStamp) AsUTC() *TimeStamp {
   301  	t.Time = toUTCTime(t.Time)
   302  	return t
   303  }
   304  
   305  // AsUTCTime Convert timestamp as time for UTC locale.
   306  func (t *TimeStamp) AsUTCTime() time.Time {
   307  	return t.Time.UTC()
   308  }
   309  
   310  // ToLocalTime Convert timestamp as time in Local locale, add +8 hours.
   311  func (t *TimeStamp) ToLocalTime() time.Time {
   312  	t.Time = toLocalTime(t.Time)
   313  	return t.Time.Local()
   314  }
   315  
   316  // ToUTCTime Convert timestamp as time in UTC locale, add -8 hours.
   317  func (t *TimeStamp) ToUTCTime() time.Time {
   318  	t.Time = toUTCTime(t.Time)
   319  	return t.Time.UTC()
   320  }
   321  
   322  // ToLocal Convert timestamp as time in Local locale, add +8 hours.
   323  func (t *TimeStamp) ToLocal() *TimeStamp {
   324  	t.Time = t.ToLocalTime()
   325  	return t
   326  }
   327  
   328  // ToUTC Convert timestamp as time in UTC locale, add -8 hours.
   329  func (t *TimeStamp) ToUTC() *TimeStamp {
   330  	t.Time = t.ToUTCTime()
   331  	return t
   332  }
   333  
   334  // AddSeconds adds seconds and return sum.
   335  func (t *TimeStamp) AddSeconds(seconds int64) *TimeStamp {
   336  	t.Time.Add(time.Duration(seconds) * time.Second)
   337  	return t
   338  }
   339  
   340  // AddMinutes adds minutes and return sum.
   341  func (t *TimeStamp) AddMinutes(minutes int64) *TimeStamp {
   342  	t.Time.Add(time.Duration(minutes) * time.Minute)
   343  	return t
   344  }
   345  
   346  // AddHours adds hours and return sum.
   347  func (t *TimeStamp) AddHours(hours int64) *TimeStamp {
   348  	t.Time.Add(time.Duration(hours) * time.Hour)
   349  	return t
   350  }
   351  
   352  // YearMonthDay returns the time's year, month, day.
   353  func (t *TimeStamp) YearMonthDay() (year, month, day int) {
   354  	return t.Time.Year(), int(t.Time.Month()), t.Time.Day()
   355  }
   356  
   357  // HourMinuteSecond returns the time's hour, minute, second.
   358  func (t *TimeStamp) HourMinuteSecond() (hour, minute, second int) {
   359  	return t.Time.Hour(), t.Time.Minute(), t.Time.Second()
   360  }
   361  
   362  // ToBytes Time MarshalBinary.
   363  func (t *TimeStamp) ToBytes() []byte {
   364  	data, _ := t.Time.MarshalBinary()
   365  	return data
   366  }
   367  
   368  // ToJSON Time MarshalJSON.
   369  func (t *TimeStamp) ToJSON() []byte {
   370  	data, _ := t.Time.MarshalJSON()
   371  	return data
   372  }
   373  
   374  // ToText Time MarshalText.
   375  func (t *TimeStamp) ToText() []byte {
   376  	data, _ := t.Time.MarshalText()
   377  	return data
   378  }
   379  
   380  // ToTime convert string to time.Time
   381  func ToTime(s string, layouts ...string) (t time.Time, err error) {
   382  	value, layout := toTimeLayout(s, layouts...)
   383  	if layout == "" {
   384  		err = ErrConvertFail
   385  		return
   386  	}
   387  	t, err = time.Parse(layout, value)
   388  	return
   389  }
   390  
   391  // ToLocalTime convert string to time.Time in Local locale, add +8 hours.
   392  func ToLocalTime(s string, layouts ...string) (t time.Time, err error) {
   393  	t, err = ToTime(s, layouts...)
   394  	if err == nil {
   395  		return toLocalTime(t).Local(), nil
   396  	}
   397  	return
   398  }
   399  
   400  // ToUTCTime convert string to time.Time in UTC locale, add -8 hours.
   401  func ToUTCTime(s string, layouts ...string) (t time.Time, err error) {
   402  	t, err = ToTime(s, layouts...)
   403  	if err == nil {
   404  		return toUTCTime(t).UTC(), nil
   405  	}
   406  	return
   407  }
   408  
   409  func toTimeLayout(s string, layouts ...string) (value string, layout string) {
   410  	value = s
   411  	if len(layouts) > 0 {
   412  		layout = layouts[0]
   413  	} else {
   414  		switch len(s) {
   415  		case 8:
   416  			layout = DateFormatStringG
   417  		case 10:
   418  			layout = DateFormatString
   419  		case 13:
   420  			layout = DateTimeFormatStringH
   421  		case 14:
   422  			layout = TimeFormatStringS
   423  		case 16:
   424  			layout = DateTimeFormatStringM
   425  		case 17:
   426  			value = value[0:14] + "." + value[14:]
   427  			layout = TimeFormatStringM
   428  		case 18:
   429  			layout = TimeFormatStringM
   430  		case 19:
   431  			layout = DateTimeFormatString
   432  		case 20, 25:
   433  			if strings.ContainsRune(s, '+') {
   434  				layout = "2006-01-02 15:04:05-07:00"
   435  			} else {
   436  				layout = time.RFC3339
   437  			}
   438  		case 23:
   439  			layout = TimeFormatString
   440  		case 29, 34:
   441  			layout = "2006-01-02 15:04:05.999999999-07:00"
   442  		case 30, 35:
   443  			layout = time.RFC3339Nano
   444  		}
   445  	}
   446  
   447  	if layout != "" {
   448  		// has 'T' eg.2006-01-02T15:04:05
   449  		if strings.ContainsRune(s, 'T') {
   450  			layout = strings.Replace(layout, " ", "T", -1)
   451  		}
   452  		// eg: 2006/01/02 15:04:05
   453  		if strings.ContainsRune(s, '/') {
   454  			layout = strings.Replace(layout, "-", "/", -1)
   455  		}
   456  	}
   457  	return
   458  }
   459  
   460  // toLocalTime Convert time, add +8 hours.
   461  func toLocalTime(t time.Time) time.Time {
   462  	return t.Add(ZoneOffsetSecond)
   463  }
   464  
   465  // toUTCTime Convert time, add -8 hours.
   466  func toUTCTime(t time.Time) time.Time {
   467  	return t.Add(-1 * ZoneOffsetSecond)
   468  }
   469  
   470  // IsDate check value is an date string.
   471  func IsDate(srcDate string) bool {
   472  	_, err := ToTime(srcDate)
   473  	return err == nil
   474  }
   475  
   476  // BeforeDate check
   477  func BeforeDate(srcDate, dstDate string) bool {
   478  	st, err := ToTime(srcDate)
   479  	if err != nil {
   480  		return false
   481  	}
   482  
   483  	dt, err := ToTime(dstDate)
   484  	if err != nil {
   485  		return false
   486  	}
   487  
   488  	return st.Before(dt)
   489  }
   490  
   491  // BeforeOrEqualDate check
   492  func BeforeOrEqualDate(srcDate, dstDate string) bool {
   493  	st, err := ToTime(srcDate)
   494  	if err != nil {
   495  		return false
   496  	}
   497  
   498  	dt, err := ToTime(dstDate)
   499  	if err != nil {
   500  		return false
   501  	}
   502  
   503  	return st.Before(dt) || st.Equal(dt)
   504  }
   505  
   506  // AfterOrEqualDate check
   507  func AfterOrEqualDate(srcDate, dstDate string) bool {
   508  	st, err := ToTime(srcDate)
   509  	if err != nil {
   510  		return false
   511  	}
   512  
   513  	dt, err := ToTime(dstDate)
   514  	if err != nil {
   515  		return false
   516  	}
   517  
   518  	return st.After(dt) || st.Equal(dt)
   519  }
   520  
   521  // AfterDate check
   522  func AfterDate(srcDate, dstDate string) bool {
   523  	st, err := ToTime(srcDate)
   524  	if err != nil {
   525  		return false
   526  	}
   527  
   528  	dt, err := ToTime(dstDate)
   529  	if err != nil {
   530  		return false
   531  	}
   532  
   533  	return st.After(dt)
   534  }