github.com/PandaGoAdmin/utils@v0.0.0-20211208134815-d5461603a00f/time.go (about)

     1  package kgo
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  	"time"
     7  )
     8  
     9  // DateFormat pattern rules.
    10  var datePatterns = []string{
    11  	// year
    12  	"Y", "2006", // A full numeric representation of a year, 4 digits   Examples: 1999 or 2003
    13  	"y", "06", // A two digit representation of a year   Examples: 99 or 03
    14  
    15  	// month
    16  	"m", "01", // Numeric representation of a month, with leading zeros 01 through 12
    17  	"n", "1", // Numeric representation of a month, without leading zeros   1 through 12
    18  	"M", "Jan", // A short textual representation of a month, three letters Jan through Dec
    19  	"F", "January", // A full textual representation of a month, such as January or March   January through December
    20  
    21  	// day
    22  	"d", "02", // Day of the month, 2 digits with leading zeros 01 to 31
    23  	"j", "2", // Day of the month without leading zeros 1 to 31
    24  
    25  	// week
    26  	"D", "Mon", // A textual representation of a day, three letters Mon through Sun
    27  	"l", "Monday", // A full textual representation of the day of the week  Sunday through Saturday
    28  
    29  	// time
    30  	"g", "3", // 12-hour format of an hour without leading zeros    1 through 12
    31  	"G", "15", // 24-hour format of an hour without leading zeros   0 through 23
    32  	"h", "03", // 12-hour format of an hour with leading zeros  01 through 12
    33  	"H", "15", // 24-hour format of an hour with leading zeros  00 through 23
    34  
    35  	"a", "pm", // Lowercase Ante meridiem and Post meridiem am or pm
    36  	"A", "PM", // Uppercase Ante meridiem and Post meridiem AM or PM
    37  
    38  	"i", "04", // Minutes with leading zeros    00 to 59
    39  	"s", "05", // Seconds, with leading zeros   00 through 59
    40  
    41  	// time zone
    42  	"T", "MST",
    43  	"P", "-07:00",
    44  	"O", "-0700",
    45  
    46  	// RFC 2822
    47  	"r", time.RFC1123Z,
    48  }
    49  
    50  // Time 获取当前Unix时间戳(秒,10位).
    51  func (kt *LkkTime) UnixTime() int64 {
    52  	return time.Now().Unix()
    53  }
    54  
    55  // MilliTime 获取当前Unix时间戳(毫秒,13位).
    56  func (kt *LkkTime) MilliTime() int64 {
    57  	return time.Now().UnixNano() / int64(time.Millisecond)
    58  }
    59  
    60  // MicroTime 获取当前Unix时间戳(微秒,16位).
    61  func (kt *LkkTime) MicroTime() int64 {
    62  	return time.Now().UnixNano() / int64(time.Microsecond)
    63  }
    64  
    65  // Str2Time 将字符串转换为时间结构.
    66  // str 为要转换的字符串;
    67  // format 为该字符串的格式,默认为"2006-01-02 15:04:05" .
    68  func (kt *LkkTime) Str2Timestruct(str string, format ...string) (time.Time, error) {
    69  	var f string
    70  	if len(format) > 0 {
    71  		f = strings.Trim(format[0], " ")
    72  	} else {
    73  		f = "2006-01-02 15:04:05"
    74  	}
    75  
    76  	if len(str) != len(f) {
    77  		return time.Now(), errors.New("[Str2Timestruct]`format error")
    78  	}
    79  
    80  	return time.ParseInLocation(f, str, Kuptime.Location())
    81  }
    82  
    83  // Str2Timestamp 将字符串转换为时间戳,秒.
    84  // str 为要转换的字符串;
    85  // format 为该字符串的格式,默认为"2006-01-02 15:04:05" .
    86  func (kt *LkkTime) Str2Timestamp(str string, format ...string) (int64, error) {
    87  	tim, err := kt.Str2Timestruct(str, format...)
    88  	if err != nil {
    89  		return 0, err
    90  	}
    91  
    92  	return tim.Unix(), nil
    93  }
    94  
    95  // Date 格式化时间.
    96  // format 格式,如"Y-m-d H:i:s".
    97  // ts为int/int64类型时间戳或time.Time类型.
    98  func (kt *LkkTime) Date(format string, ts ...interface{}) string {
    99  	replacer := strings.NewReplacer(datePatterns...)
   100  	format = replacer.Replace(format)
   101  
   102  	var t time.Time
   103  	if len(ts) > 0 {
   104  		val := ts[0]
   105  		if v, ok := val.(time.Time); ok {
   106  			t = v
   107  		} else if v, ok := val.(int); ok {
   108  			t = time.Unix(int64(v), 0)
   109  		} else if v, ok := val.(int64); ok {
   110  			t = time.Unix(int64(v), 0)
   111  		} else {
   112  			return ""
   113  		}
   114  	} else {
   115  		t = time.Now()
   116  	}
   117  
   118  	return t.Format(format)
   119  }
   120  
   121  // CheckDate 检查是否正常的日期.
   122  func (kt *LkkTime) CheckDate(year, month, day int) bool {
   123  	if month < 1 || month > 12 || day < 1 || day > 31 || year < 1 || year > 32767 {
   124  		return false
   125  	}
   126  	switch month {
   127  	case 4, 6, 9, 11:
   128  		if day > 30 {
   129  			return false
   130  		}
   131  	case 2:
   132  		// leap year
   133  		if year%4 == 0 && (year%100 != 0 || year%400 == 0) {
   134  			if day > 29 {
   135  				return false
   136  			}
   137  		} else if day > 28 {
   138  			return false
   139  		}
   140  	}
   141  
   142  	return true
   143  }
   144  
   145  // Sleep 延缓执行,秒.
   146  func (kt *LkkTime) Sleep(t int64) {
   147  	time.Sleep(time.Duration(t) * time.Second)
   148  }
   149  
   150  // Usleep 以指定的微秒数延迟执行.
   151  func (kt *LkkTime) Usleep(t int64) {
   152  	time.Sleep(time.Duration(t) * time.Microsecond)
   153  }
   154  
   155  // ServiceStartime 获取当前服务启动时间戳,秒.
   156  func (kt *LkkTime) ServiceStartime() int64 {
   157  	return Kuptime.Unix()
   158  }
   159  
   160  // ServiceUptime 获取当前服务运行时间,纳秒int64.
   161  func (kt *LkkTime) ServiceUptime() time.Duration {
   162  	return time.Since(Kuptime)
   163  }
   164  
   165  // GetMonthDays 获取指定月份的天数.year年份,可选,默认当前年份.
   166  func (kt *LkkTime) GetMonthDays(month int, year ...int) (days int) {
   167  	if month < 1 || month > 12 {
   168  		return
   169  	}
   170  
   171  	var yr int
   172  	if len(year) == 0 {
   173  		yr = time.Now().Year()
   174  	} else {
   175  		yr = year[0]
   176  	}
   177  
   178  	if month != 2 {
   179  		if month == 4 || month == 6 || month == 9 || month == 11 {
   180  			days = 30
   181  		} else {
   182  			days = 31
   183  		}
   184  	} else {
   185  		if ((yr%4) == 0 && (yr%100) != 0) || (yr%400) == 0 {
   186  			days = 29
   187  		} else {
   188  			days = 28
   189  		}
   190  	}
   191  
   192  	return
   193  }
   194  
   195  // Year 获取年份.
   196  func (kt *LkkTime) Year(t ...time.Time) int {
   197  	var tm time.Time
   198  	if len(t) > 0 {
   199  		tm = t[0]
   200  	} else {
   201  		tm = time.Now()
   202  	}
   203  	return tm.Year()
   204  }
   205  
   206  // Month 获取月份.
   207  func (kt *LkkTime) Month(t ...time.Time) int {
   208  	var tm time.Time
   209  	if len(t) > 0 {
   210  		tm = t[0]
   211  	} else {
   212  		tm = time.Now()
   213  	}
   214  	return int(tm.Month())
   215  }
   216  
   217  // Day 获取日份.
   218  func (kt *LkkTime) Day(t ...time.Time) int {
   219  	var tm time.Time
   220  	if len(t) > 0 {
   221  		tm = t[0]
   222  	} else {
   223  		tm = time.Now()
   224  	}
   225  	return tm.Day()
   226  }
   227  
   228  // Hour 获取小时.
   229  func (kt *LkkTime) Hour(t ...time.Time) int {
   230  	var tm time.Time
   231  	if len(t) > 0 {
   232  		tm = t[0]
   233  	} else {
   234  		tm = time.Now()
   235  	}
   236  	return tm.Hour()
   237  }
   238  
   239  // Minute 获取分钟.
   240  func (kt *LkkTime) Minute(t ...time.Time) int {
   241  	var tm time.Time
   242  	if len(t) > 0 {
   243  		tm = t[0]
   244  	} else {
   245  		tm = time.Now()
   246  	}
   247  	return tm.Minute()
   248  }
   249  
   250  // Second 获取秒数.
   251  func (kt *LkkTime) Second(t ...time.Time) int {
   252  	var tm time.Time
   253  	if len(t) > 0 {
   254  		tm = t[0]
   255  	} else {
   256  		tm = time.Now()
   257  	}
   258  	return tm.Second()
   259  }
   260  
   261  // StartOfDay 获取日期中当天的开始时间.
   262  func (kt *LkkTime) StartOfDay(date time.Time) time.Time {
   263  	return time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
   264  }
   265  
   266  // EndOfDay 获取日期中当天的结束时间.
   267  func (kt *LkkTime) EndOfDay(date time.Time) time.Time {
   268  	return time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, int(time.Second-time.Nanosecond), date.Location())
   269  }
   270  
   271  // StartOfMonth 获取日期中当月的开始时间.
   272  func (kt *LkkTime) StartOfMonth(date time.Time) time.Time {
   273  	return time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, date.Location())
   274  }
   275  
   276  // EndOfMonth 获取日期中当月的结束时间.
   277  func (kt *LkkTime) EndOfMonth(date time.Time) time.Time {
   278  	return kt.StartOfMonth(date).AddDate(0, 1, 0).Add(-time.Nanosecond)
   279  }
   280  
   281  // StartOfYear 获取日期中当年的开始时间.
   282  func (kt *LkkTime) StartOfYear(date time.Time) time.Time {
   283  	return time.Date(date.Year(), 1, 1, 0, 0, 0, 0, date.Location())
   284  }
   285  
   286  // EndOfYear 获取日期中当年的结束时间.
   287  func (kt *LkkTime) EndOfYear(date time.Time) time.Time {
   288  	return kt.StartOfYear(date).AddDate(1, 0, 0).Add(-time.Nanosecond)
   289  }
   290  
   291  // StartOfWeek 获取日期中当周的开始时间;
   292  // weekStartDay 周几作为周的第一天,本库默认周一.
   293  func (kt *LkkTime) StartOfWeek(date time.Time, weekStartDay ...time.Weekday) time.Time {
   294  	weekstart := time.Monday
   295  	if len(weekStartDay) > 0 {
   296  		weekstart = weekStartDay[0]
   297  	}
   298  
   299  	// 当前是周几
   300  	weekday := int(date.Weekday())
   301  	if weekstart != time.Sunday {
   302  		weekStartDayInt := int(weekstart)
   303  
   304  		if weekday < weekStartDayInt {
   305  			weekday = weekday + 7 - weekStartDayInt
   306  		} else {
   307  			weekday = weekday - weekStartDayInt
   308  		}
   309  	}
   310  
   311  	return time.Date(date.Year(), date.Month(), date.Day()-weekday, 0, 0, 0, 0, date.Location())
   312  }
   313  
   314  // EndOfWeek 获取日期中当周的结束时间;
   315  // weekStartDay 周几作为周的第一天,本库默认周一.
   316  func (kt *LkkTime) EndOfWeek(date time.Time, weekStartDay ...time.Weekday) time.Time {
   317  	return kt.StartOfWeek(date, weekStartDay...).AddDate(0, 0, 7).Add(-time.Nanosecond)
   318  }
   319  
   320  // DaysBetween 获取两个日期的间隔天数.
   321  // fromDate 为开始时间,toDate 为终点时间.
   322  func (kt *LkkTime) DaysBetween(fromDate, toDate time.Time) int {
   323  	return int(toDate.Sub(fromDate) / (24 * time.Hour))
   324  }
   325  
   326  // IsDate2time 检查字符串是否日期格式,并转换为时间戳.注意,时间戳可能为负数(小于1970年时).
   327  // 匹配如:
   328  //	0000
   329  //	0000-00
   330  //	0000/00
   331  //	0000-00-00
   332  //	0000/00/00
   333  //	0000-00-00 00
   334  //	0000/00/00 00
   335  //	0000-00-00 00:00
   336  //	0000/00/00 00:00
   337  //	0000-00-00 00:00:00
   338  //	0000/00/00 00:00:00
   339  // 等日期格式.
   340  func (kt *LkkTime) IsDate2time(str string) (bool, int64) {
   341  	if str == "" {
   342  		return false, 0
   343  	} else if strings.ContainsRune(str, '/') {
   344  		str = strings.Replace(str, "/", "-", -1)
   345  	}
   346  
   347  	chk := RegDatetime.MatchString(str)
   348  	if !chk {
   349  		return false, 0
   350  	}
   351  
   352  	leng := len(str)
   353  	if leng < 19 {
   354  		reference := "1970-01-01 00:00:00"
   355  		str = str + reference[leng:19]
   356  	}
   357  
   358  	tim, err := KTime.Str2Timestamp(str)
   359  	if err != nil {
   360  		return false, 0
   361  	}
   362  
   363  	return true, tim
   364  }