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.
217 lines
5.8 KiB
217 lines
5.8 KiB
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) |
|
}
|
|
|