You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
5.8 KiB
218 lines
5.8 KiB
3 years ago
|
package now
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"regexp"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// BeginningOfMinute beginning of minute
|
||
|
func (now *Now) BeginningOfMinute() time.Time {
|
||
|
return now.Truncate(time.Minute)
|
||
|
}
|
||
|
|
||
|
// BeginningOfHour beginning of hour
|
||
|
func (now *Now) BeginningOfHour() time.Time {
|
||
|
y, m, d := now.Date()
|
||
|
return time.Date(y, m, d, now.Time.Hour(), 0, 0, 0, now.Time.Location())
|
||
|
}
|
||
|
|
||
|
// BeginningOfDay beginning of day
|
||
|
func (now *Now) BeginningOfDay() time.Time {
|
||
|
y, m, d := now.Date()
|
||
|
return time.Date(y, m, d, 0, 0, 0, 0, now.Time.Location())
|
||
|
}
|
||
|
|
||
|
// BeginningOfWeek beginning of week
|
||
|
func (now *Now) BeginningOfWeek() time.Time {
|
||
|
t := now.BeginningOfDay()
|
||
|
weekday := int(t.Weekday())
|
||
|
|
||
|
if now.WeekStartDay != time.Sunday {
|
||
|
weekStartDayInt := int(now.WeekStartDay)
|
||
|
|
||
|
if weekday < weekStartDayInt {
|
||
|
weekday = weekday + 7 - weekStartDayInt
|
||
|
} else {
|
||
|
weekday = weekday - weekStartDayInt
|
||
|
}
|
||
|
}
|
||
|
return t.AddDate(0, 0, -weekday)
|
||
|
}
|
||
|
|
||
|
// BeginningOfMonth beginning of month
|
||
|
func (now *Now) BeginningOfMonth() time.Time {
|
||
|
y, m, _ := now.Date()
|
||
|
return time.Date(y, m, 1, 0, 0, 0, 0, now.Location())
|
||
|
}
|
||
|
|
||
|
// BeginningOfQuarter beginning of quarter
|
||
|
func (now *Now) BeginningOfQuarter() time.Time {
|
||
|
month := now.BeginningOfMonth()
|
||
|
offset := (int(month.Month()) - 1) % 3
|
||
|
return month.AddDate(0, -offset, 0)
|
||
|
}
|
||
|
|
||
|
// BeginningOfHalf beginning of half year
|
||
|
func (now *Now) BeginningOfHalf() time.Time {
|
||
|
month := now.BeginningOfMonth()
|
||
|
offset := (int(month.Month()) - 1) % 6
|
||
|
return month.AddDate(0, -offset, 0)
|
||
|
}
|
||
|
|
||
|
// BeginningOfYear BeginningOfYear beginning of year
|
||
|
func (now *Now) BeginningOfYear() time.Time {
|
||
|
y, _, _ := now.Date()
|
||
|
return time.Date(y, time.January, 1, 0, 0, 0, 0, now.Location())
|
||
|
}
|
||
|
|
||
|
// EndOfMinute end of minute
|
||
|
func (now *Now) EndOfMinute() time.Time {
|
||
|
return now.BeginningOfMinute().Add(time.Minute - time.Nanosecond)
|
||
|
}
|
||
|
|
||
|
// EndOfHour end of hour
|
||
|
func (now *Now) EndOfHour() time.Time {
|
||
|
return now.BeginningOfHour().Add(time.Hour - time.Nanosecond)
|
||
|
}
|
||
|
|
||
|
// EndOfDay end of day
|
||
|
func (now *Now) EndOfDay() time.Time {
|
||
|
y, m, d := now.Date()
|
||
|
return time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), now.Location())
|
||
|
}
|
||
|
|
||
|
// EndOfWeek end of week
|
||
|
func (now *Now) EndOfWeek() time.Time {
|
||
|
return now.BeginningOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond)
|
||
|
}
|
||
|
|
||
|
// EndOfMonth end of month
|
||
|
func (now *Now) EndOfMonth() time.Time {
|
||
|
return now.BeginningOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond)
|
||
|
}
|
||
|
|
||
|
// EndOfQuarter end of quarter
|
||
|
func (now *Now) EndOfQuarter() time.Time {
|
||
|
return now.BeginningOfQuarter().AddDate(0, 3, 0).Add(-time.Nanosecond)
|
||
|
}
|
||
|
|
||
|
// EndOfHalf end of half year
|
||
|
func (now *Now) EndOfHalf() time.Time {
|
||
|
return now.BeginningOfHalf().AddDate(0, 6, 0).Add(-time.Nanosecond)
|
||
|
}
|
||
|
|
||
|
// EndOfYear end of year
|
||
|
func (now *Now) EndOfYear() time.Time {
|
||
|
return now.BeginningOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond)
|
||
|
}
|
||
|
|
||
|
// Monday monday
|
||
|
func (now *Now) Monday() time.Time {
|
||
|
t := now.BeginningOfDay()
|
||
|
weekday := int(t.Weekday())
|
||
|
if weekday == 0 {
|
||
|
weekday = 7
|
||
|
}
|
||
|
return t.AddDate(0, 0, -weekday+1)
|
||
|
}
|
||
|
|
||
|
// Sunday sunday
|
||
|
func (now *Now) Sunday() time.Time {
|
||
|
t := now.BeginningOfDay()
|
||
|
weekday := int(t.Weekday())
|
||
|
if weekday == 0 {
|
||
|
return t
|
||
|
}
|
||
|
return t.AddDate(0, 0, (7 - weekday))
|
||
|
}
|
||
|
|
||
|
// EndOfSunday end of sunday
|
||
|
func (now *Now) EndOfSunday() time.Time {
|
||
|
return New(now.Sunday()).EndOfDay()
|
||
|
}
|
||
|
|
||
|
// Quarter returns the yearly quarter
|
||
|
func (now *Now) Quarter() uint {
|
||
|
return (uint(now.Month())-1)/3 + 1
|
||
|
}
|
||
|
|
||
|
func (now *Now) parseWithFormat(str string, location *time.Location) (t time.Time, err error) {
|
||
|
for _, format := range now.TimeFormats {
|
||
|
t, err = time.ParseInLocation(format, str, location)
|
||
|
|
||
|
if err == nil {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
err = errors.New("Can't parse string as time: " + str)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var hasTimeRegexp = regexp.MustCompile(`(\s+|^\s*|T)\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))(\s*$|[Z+-])`) // match 15:04:05, 15:04:05.000, 15:04:05.000000 15, 2017-01-01 15:04, 2021-07-20T00:59:10Z, 2021-07-20T00:59:10+08:00, 2021-07-20T00:00:10-07:00 etc
|
||
|
var onlyTimeRegexp = regexp.MustCompile(`^\s*\d{1,2}((:\d{1,2})*|((:\d{1,2}){2}\.(\d{3}|\d{6}|\d{9})))\s*$`) // match 15:04:05, 15, 15:04:05.000, 15:04:05.000000, etc
|
||
|
|
||
|
// Parse parse string to time
|
||
|
func (now *Now) Parse(strs ...string) (t time.Time, err error) {
|
||
|
var (
|
||
|
setCurrentTime bool
|
||
|
parseTime []int
|
||
|
currentLocation = now.Location()
|
||
|
onlyTimeInStr = true
|
||
|
currentTime = formatTimeToList(now.Time)
|
||
|
)
|
||
|
|
||
|
for _, str := range strs {
|
||
|
hasTimeInStr := hasTimeRegexp.MatchString(str) // match 15:04:05, 15
|
||
|
onlyTimeInStr = hasTimeInStr && onlyTimeInStr && onlyTimeRegexp.MatchString(str)
|
||
|
if t, err = now.parseWithFormat(str, currentLocation); err == nil {
|
||
|
location := t.Location()
|
||
|
parseTime = formatTimeToList(t)
|
||
|
|
||
|
for i, v := range parseTime {
|
||
|
// Don't reset hour, minute, second if current time str including time
|
||
|
if hasTimeInStr && i <= 3 {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// If value is zero, replace it with current time
|
||
|
if v == 0 {
|
||
|
if setCurrentTime {
|
||
|
parseTime[i] = currentTime[i]
|
||
|
}
|
||
|
} else {
|
||
|
setCurrentTime = true
|
||
|
}
|
||
|
|
||
|
// if current time only includes time, should change day, month to current time
|
||
|
if onlyTimeInStr {
|
||
|
if i == 4 || i == 5 {
|
||
|
parseTime[i] = currentTime[i]
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
t = time.Date(parseTime[6], time.Month(parseTime[5]), parseTime[4], parseTime[3], parseTime[2], parseTime[1], parseTime[0], location)
|
||
|
currentTime = formatTimeToList(t)
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// MustParse must parse string to time or it will panic
|
||
|
func (now *Now) MustParse(strs ...string) (t time.Time) {
|
||
|
t, err := now.Parse(strs...)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return t
|
||
|
}
|
||
|
|
||
|
// Between check time between the begin, end time or not
|
||
|
func (now *Now) Between(begin, end string) bool {
|
||
|
beginTime := now.MustParse(begin)
|
||
|
endTime := now.MustParse(end)
|
||
|
return now.After(beginTime) && now.Before(endTime)
|
||
|
}
|