commit 50ead3d72ab8b45ef82afe614954a1c2fe08c12a Author: 李光春 Date: Fri Mar 4 17:45:21 2022 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88685d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.env +.git +.svn +.idea +.vscode +.log diff --git a/Tomorrow.go b/Tomorrow.go new file mode 100644 index 0000000..e91268f --- /dev/null +++ b/Tomorrow.go @@ -0,0 +1,15 @@ +package gotime + +import "time" + +// Tomorrow 明天 +func Tomorrow() Pro { + p := NewPro() + location, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + p.Time = time.Now().Add(time.Hour*8).AddDate(0, 0, +1) + } else { + p.Time = time.Now().In(location).AddDate(0, 0, +1) + } + return p +} diff --git a/app.go b/app.go new file mode 100644 index 0000000..b10633b --- /dev/null +++ b/app.go @@ -0,0 +1,91 @@ +package gotime + +import ( + "fmt" + "time" +) + +// 时间格式化常量 +const ( + RFC3339Format = time.RFC3339 + Iso8601Format = "2006-01-02T15:04:05-07:00" + CookieFormat = "Monday, 02-Jan-2006 15:04:05 MST" + RFC1036Format = "Mon, 02 Jan 06 15:04:05 -0700" + RFC7231Format = "Mon, 02 Jan 2006 15:04:05 GMT" + DayDateTimeFormat = "Mon, Jan 2, 2006 3:04 PM" + DateTimeFormat = "2006-01-02 15:04:05" + DateFormat = "2006-01-02" + TimeFormat = "15:04:05" + ShortDateTimeFormat = "20060102150405" + ShortDateFormat = "20060102" + ShortTimeFormat = "150405" +) + +// Pro 结构体 +type Pro struct { + Time time.Time + loc *time.Location + Error error +} + +// NewPro 初始化结构体 +func NewPro() Pro { + return Pro{ + Time: time.Now(), + } +} + +// BeforeSeconds 获取n秒前的时间 +func (p Pro) BeforeSeconds(seconds int) Pro { + st, _ := time.ParseDuration(fmt.Sprintf("-%ds", seconds)) + p.Time = p.Time.Add(st) + return p +} + +// AfterSeconds 获取n秒后的时间 +func (p Pro) AfterSeconds(seconds int) Pro { + st, _ := time.ParseDuration(fmt.Sprintf("+%ds", seconds)) + p.Time = p.Time.Add(st) + return p +} + +// BeforeHour 获取n小时前的时间 +func (p Pro) BeforeHour(hour int) Pro { + st, _ := time.ParseDuration(fmt.Sprintf("-%dh", hour)) + p.Time = p.Time.Add(st) + return p +} + +// AfterHour 获取n小时后的时间 +func (p Pro) AfterHour(hour int) Pro { + st, _ := time.ParseDuration(fmt.Sprintf("+%dh", hour)) + p.Time = p.Time.Add(st) + return p +} + +// BeforeDay 获取n天前的时间 +func (p Pro) BeforeDay(day int) Pro { + p.Time = p.Time.AddDate(0, 0, -day) + return p +} + +// AfterDay 获取n天后的时间 +func (p Pro) AfterDay(day int) Pro { + p.Time = p.Time.AddDate(0, 0, day) + return p +} + +// SetFormat 格式化 +func (p Pro) SetFormat(layout string) string { + return p.Time.Format(layout) +} + +// Month 获取当前月 +func (p Pro) Month() int { + return p.MonthOfYear() +} + +// MonthOfYear 获取本年的第几月 +func (p Pro) MonthOfYear() int { + return int(p.Time.In(p.loc).Month()) +} diff --git a/app_test.go b/app_test.go new file mode 100644 index 0000000..5fb7ea8 --- /dev/null +++ b/app_test.go @@ -0,0 +1,124 @@ +package gotime + +import ( + "testing" +) + +func TestTime(t *testing.T) { + t.Log("今天此刻:", Current().Now()) + t.Log("今天此刻格式化:", Current().Format()) + t.Log("今天此刻日期:", Current().ToDateFormat()) + t.Log("今天此刻时间:", Current().ToTimeFormat()) + t.Log("今天此刻时间戳:", Current().Timestamp()) + t.Log("今天此刻时间戳:", Current().TimestampWithSecond()) + t.Log("今天毫秒级时间戳:", Current().TimestampWithMillisecond()) + t.Log("今天微秒级时间戳:", Current().TimestampWithMicrosecond()) + t.Log("今天纳秒级时间戳:", Current().TimestampWithNanosecond()) + + t.Log("昨天此刻:", Yesterday().Now()) + t.Log("昨天此刻格式化:", Yesterday().Format()) + t.Log("昨天此刻日期:", Yesterday().ToDateFormat()) + t.Log("昨天此刻时间:", Yesterday().ToTimeFormat()) + t.Log("昨天此刻时间戳:", Yesterday().Timestamp()) + t.Log("昨天此刻时间戳:", Yesterday().TimestampWithSecond()) + t.Log("昨天毫秒级时间戳:", Yesterday().TimestampWithMillisecond()) + t.Log("昨天微秒级时间戳:", Yesterday().TimestampWithMicrosecond()) + t.Log("昨天纳秒级时间戳:", Yesterday().TimestampWithNanosecond()) + + t.Log("明天此刻:", Tomorrow().Now()) + t.Log("明天此刻格式化:", Tomorrow().Format()) + t.Log("明天此刻日期:", Tomorrow().ToDateFormat()) + t.Log("明天此刻时间:", Tomorrow().ToTimeFormat()) + t.Log("明天此刻时间戳:", Tomorrow().Timestamp()) + t.Log("明天此刻时间戳:", Tomorrow().TimestampWithSecond()) + t.Log("明天毫秒级时间戳:", Tomorrow().TimestampWithMillisecond()) + t.Log("明天微秒级时间戳:", Tomorrow().TimestampWithMicrosecond()) + t.Log("明天纳秒级时间戳:", Tomorrow().TimestampWithNanosecond()) + + t.Log("本世纪开始时间:", Current().StartOfCentury().Format()) + t.Log("本世纪结束时间:", Current().EndOfCentury().Format()) + t.Log("本年代开始时间:", Current().StartOfDecade().Format()) + t.Log("本年代结束时间:", Current().EndOfDecade().Format()) + t.Log("本年开始时间:", Current().StartOfYear().Format()) + t.Log("本年结束时间:", Current().EndOfYear().Format()) + t.Log("本季度开始时间:", Current().StartOfQuarter().Format()) + t.Log("本季度结束时间:", Current().EndOfQuarter().Format()) + t.Log("本月开始时间:", Current().StartOfMonth().Format()) + t.Log("本月结束时间:", Current().EndOfMonth().Format()) + + //t.Log("7100秒前的时间:", Current().BeforeSeconds(7100).Format()) + //t.Log("2小时前的时间:", Current().BeforeHour(2).Format()) + //t.Log("7100秒后的时间:", Current().AfterSeconds(7100).Format()) + //t.Log("2小时后的时间:", Current().AfterHour(2).Format()) +} + +func TestStartOfDay(t *testing.T) { + t.Log(Current().Format()) + t.Log(Current().StartOfDay().Format()) + t.Log(Current().EndOfDay().Format()) + t.Log(Current().Timestamp()) + t.Log(Current().StartOfDay().Timestamp()) + t.Log(Current().EndOfDay().Timestamp()) + t.Log(Current().BeforeDay(1).Format()) + t.Log(Current().BeforeDay(1).StartOfDay().Format()) + t.Log(Current().BeforeDay(1).EndOfDay().Format()) + t.Log(Current().AfterDay(1).Format()) + t.Log(Current().AfterDay(1).StartOfDay().Format()) + t.Log(Current().AfterDay(1).EndOfDay().Format()) +} + +func TestDiff(t *testing.T) { + t.Log(Current().DiffInHourWithAbs(SetCurrentParse("2021-11-26 14:50:00").Time)) + t.Log(Current().DiffInHour(SetCurrentParse("2021-11-26 14:50:00").Time)) + t.Log(Current().DiffInMinutesWithAbs(SetCurrentParse("2021-11-26 14:50:00").Time)) + t.Log(Current().DiffInMinutes(SetCurrentParse("2021-11-26 14:50:00").Time)) + t.Log(SetCurrentParse("2022-03-01T10:03:39+08:00").Format()) + t.Log(SetCurrentParse("2022-03-04T11:12:47+08:00").Format()) +} + +func TestUnix(t *testing.T) { + t.Log(SetCurrentUnix(1640067240).Format()) + t.Log(Current().BeforeDay(3 - 2).StartOfDay().Format()) + t.Log(Current().BeforeDay(3 - 1).EndOfDay().Format()) +} + +func Test2(t *testing.T) { + t.Log(Current().BeforeDay(1 + 1).Format()) + t.Log(Current().BeforeDay(1).Format()) + t.Log(Current().BeforeHour(24).Format()) + t.Log(Current().Format()) +} + +func TestTaoBao(t *testing.T) { + i := 1 + for { + if i > 3 { + break + } + t.Log(i) + t.Log(i * 24) + t.Log((i * 24) - 24) + t.Log(Current().BeforeHour(i * 24).Format()) + t.Log(Current().BeforeHour((i * 24) - 24).Format()) + i++ + } +} + +func TestMT(t *testing.T) { + + day := 1 + t.Log(day) + t.Log(Current().BeforeHour(24 * day).Format()) + t.Log(Current().BeforeHour(24 * (day - 1)).Format()) + + day = 2 + t.Log(day) + t.Log(Current().BeforeHour(24 * day).Format()) + t.Log(Current().BeforeHour(24 * (day - 1)).Format()) + + day = 3 + t.Log(day) + t.Log(Current().BeforeHour(24 * day).Format()) + t.Log(Current().BeforeHour(24 * (day - 1)).Format()) + +} diff --git a/differ.go b/differ.go new file mode 100644 index 0000000..0ad3033 --- /dev/null +++ b/differ.go @@ -0,0 +1,69 @@ +package gotime + +import "time" + +// DiffInHour 相差多少小时 +func (p Pro) DiffInHour(t2 time.Time) (hour int64) { + t2.Before(p.Time) + diff := p.Time.Unix() - t2.Unix() + hour = diff / 3600 + return hour +} + +// DiffInHourWithAbs 相差多少小时(绝对值) +func (p Pro) DiffInHourWithAbs(t2 time.Time) (hour int64) { + p.Time.Before(t2) + diff := t2.Unix() - p.Time.Unix() + hour = diff / 3600 + if hour > 0 { + return hour + } + t2.Before(p.Time) + diff = p.Time.Unix() - t2.Unix() + hour = diff / 3600 + return hour +} + +// DiffInMinutes 相差多少分钟 +func (p Pro) DiffInMinutes(t2 time.Time) (hour int64) { + t2.Before(p.Time) + diff := p.Time.Unix() - t2.Unix() + hour = diff / 60 + return hour +} + +// DiffInMinutesWithAbs 相差多少分钟(绝对值) +func (p Pro) DiffInMinutesWithAbs(t2 time.Time) (hour int64) { + p.Time.Before(t2) + diff := t2.Unix() - p.Time.Unix() + hour = diff / 60 + if hour > 0 { + return hour + } + t2.Before(p.Time) + diff = p.Time.Unix() - t2.Unix() + hour = diff / 60 + return hour +} + +// DiffInSecond 相差多少秒 +func (p Pro) DiffInSecond(t2 time.Time) (hour int64) { + t2.Before(p.Time) + diff := p.Time.Unix() - t2.Unix() + hour = diff + return hour +} + +// DiffInSecondWithAbs 相差多少秒(绝对值) +func (p Pro) DiffInSecondWithAbs(t2 time.Time) (hour int64) { + p.Time.Before(t2) + diff := t2.Unix() - p.Time.Unix() + hour = diff + if hour > 0 { + return hour + } + t2.Before(p.Time) + diff = p.Time.Unix() - t2.Unix() + hour = diff + return hour +} diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..2f69622 --- /dev/null +++ b/errors.go @@ -0,0 +1,8 @@ +package gotime + +import "fmt" + +// invalidTimezoneError 无效的时区错误 +var invalidTimezoneError = func(timezone string) error { + return fmt.Errorf("invalid timezone %q, please see the file %q for all valid timezones", timezone, "$GOROOT/lib/time/zoneinfo.zip") +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..db4530b --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module gitee.com/dtapps/go-time + +go 1.17 diff --git a/location.go b/location.go new file mode 100644 index 0000000..1b664ab --- /dev/null +++ b/location.go @@ -0,0 +1,14 @@ +package gotime + +import ( + "time" +) + +// 通过时区获取 Location 实例 +func getLocationByTimezone(timezone string) (*time.Location, error) { + loc, err := time.LoadLocation(timezone) + if err != nil { + err = invalidTimezoneError(timezone) + } + return loc, err +} diff --git a/start_end.go b/start_end.go new file mode 100644 index 0000000..5afb4f5 --- /dev/null +++ b/start_end.go @@ -0,0 +1,124 @@ +package gotime + +import "time" + +// 数字常量 +const ( + YearsPerMillennium = 1000 // 每千年1000年 + YearsPerCentury = 100 // 每世纪100年 + YearsPerDecade = 10 // 每十年10年 + QuartersPerYear = 4 // 每年4季度 + MonthsPerYear = 12 // 每年12月 + MonthsPerQuarter = 3 // 每季度3月 + WeeksPerNormalYear = 52 // 每常规年52周 + weeksPerLongYear = 53 // 每长年53周 + WeeksPerMonth = 4 // 每月4周 + DaysPerLeapYear = 366 // 每闰年366天 + DaysPerNormalYear = 365 // 每常规年365天 + DaysPerWeek = 7 // 每周7天 + HoursPerWeek = 168 // 每周168小时 + HoursPerDay = 24 // 每天24小时 + MinutesPerDay = 1440 // 每天1440分钟 + MinutesPerHour = 60 // 每小时60分钟 + SecondsPerWeek = 604800 // 每周604800秒 + SecondsPerDay = 86400 // 每天86400秒 + SecondsPerHour = 3600 // 每小时3600秒 + SecondsPerMinute = 60 // 每分钟60秒 + MillisecondsPerSecond = 1000 // 每秒1000毫秒 + MicrosecondsPerMillisecond = 1000 // 每毫秒1000微秒 + MicrosecondsPerSecond = 1000000 // 每秒1000000微秒 +) + +// StartOfCentury 本世纪开始时间 +func (p Pro) StartOfCentury() Pro { + p.Time = time.Date(p.Time.Year()/YearsPerCentury*YearsPerCentury, 1, 1, 0, 0, 0, 0, p.Time.Location()) + return p +} + +// EndOfCentury 本世纪结束时间 +func (p Pro) EndOfCentury() Pro { + p.Time = time.Date(p.Time.Year()/YearsPerCentury*YearsPerCentury+99, 12, 31, 23, 59, 59, 999999999, p.Time.Location()) + return p +} + +// StartOfDecade 本年代开始时间 +func (p Pro) StartOfDecade() Pro { + p.Time = time.Date(p.Time.Year()/YearsPerDecade*YearsPerDecade, 1, 1, 0, 0, 0, 0, p.Time.Location()) + return p +} + +// EndOfDecade 本年代结束时间 +func (p Pro) EndOfDecade() Pro { + p.Time = time.Date(p.Time.Year()/YearsPerDecade*YearsPerDecade+9, 12, 31, 23, 59, 59, 999999999, p.Time.Location()) + return p +} + +// StartOfYear 本年开始时间 +func (p Pro) StartOfYear() Pro { + p.Time = time.Date(p.Time.Year(), 1, 1, 0, 0, 0, 0, p.Time.Location()) + return p +} + +// EndOfYear 本年结束时间 +func (p Pro) EndOfYear() Pro { + p.Time = time.Date(p.Time.Year(), 12, 31, 23, 59, 59, 999999999, p.Time.Location()) + return p +} + +// Quarter 获取当前季度 +func (p Pro) Quarter() (quarter int) { + switch { + case p.Time.Month() >= 10: + quarter = 4 + case p.Time.Month() >= 7: + quarter = 3 + case p.Time.Month() >= 4: + quarter = 2 + case p.Time.Month() >= 1: + quarter = 1 + } + return +} + +// StartOfQuarter 本季度开始时间 +func (p Pro) StartOfQuarter() Pro { + p.Time = time.Date(p.Time.Year(), time.Month(3*p.Quarter()-2), 1, 0, 0, 0, 0, p.Time.Location()) + return p +} + +// EndOfQuarter 本季度结束时间 +func (p Pro) EndOfQuarter() Pro { + quarter, day := p.Quarter(), 30 + switch quarter { + case 1, 4: + day = 31 + case 2, 3: + day = 30 + } + p.Time = time.Date(p.Time.Year(), time.Month(3*quarter), day, 23, 59, 59, 999999999, p.Time.Location()) + return p +} + +// StartOfMonth 本月开始时间 +func (p Pro) StartOfMonth() Pro { + p.Time = time.Date(p.Time.Year(), time.Month(p.Month()), 1, 0, 0, 0, 0, p.Time.Location()) + return p +} + +// EndOfMonth 本月结束时间 +func (p Pro) EndOfMonth() Pro { + p.Time = time.Date(p.Time.Year(), time.Month(p.Month()), 1, 23, 59, 59, 999999999, p.Time.Location()) + return p +} + +// StartOfDay 本日开始时间 +func (p Pro) StartOfDay() Pro { + p.Time = time.Date(p.Time.Year(), p.Time.Month(), p.Time.Day(), 0, 0, 0, 0, p.Time.Location()) + return p +} + +// EndOfDay 本日结束时间 +func (p Pro) EndOfDay() Pro { + p.Time = time.Date(p.Time.Year(), p.Time.Month(), p.Time.Day(), 23, 59, 59, 0, p.Time.Location()) + return p +} diff --git a/today.go b/today.go new file mode 100644 index 0000000..f19f505 --- /dev/null +++ b/today.go @@ -0,0 +1,112 @@ +package gotime + +import ( + "log" + "strconv" + "strings" + "time" +) + +// Current 获取当前的时间 +func Current() Pro { + p := NewPro() + p.loc, p.Error = time.LoadLocation("Asia/Shanghai") + if p.Error != nil { + // Docker部署golang应用时时区问题 https://www.ddhigh.com/2018/03/01/golang-docker-timezone.html + log.Printf("【gotime】时区错误:%v\n", p.Error) + p.Time = time.Now().Add(time.Hour * 8) + } else { + p.Time = time.Now().In(p.loc) + } + return p +} + +// SetCurrent 设置当前的时间 +func SetCurrent(sTime time.Time) Pro { + p := NewPro() + p.Time = sTime + return p +} + +// SetCurrentParse 设置当前的时间 +func SetCurrentParse(str string) Pro { + + p := NewPro() + + p.loc, p.Error = time.LoadLocation("Asia/Shanghai") + + layout := DateTimeFormat + if str == "" || str == "0" || str == "0000-00-00 00:00:00" || str == "0000-00-00" || str == "00:00:00" { + return p + } + if len(str) == 10 && strings.Count(str, "-") == 2 { + layout = DateFormat + } + if strings.Index(str, "T") == 10 { + layout = RFC3339Format + } + if _, err := strconv.ParseInt(str, 10, 64); err == nil { + switch len(str) { + case 8: + layout = ShortDateFormat + case 14: + layout = ShortDateTimeFormat + } + } + location, _ := time.ParseInLocation(layout, str, p.loc) + + p.Time = location + return p +} + +// SetCurrentUnix 设置当前的时间 Unix时间戳 +func SetCurrentUnix(ts int64) Pro { + p := NewPro() + p.Time = time.Unix(ts, 0) + return p +} + +// Now 今天此刻 +func (p Pro) Now() time.Time { + return p.Time +} + +// Format 今天此刻格式化 +func (p Pro) Format() string { + return p.Time.Format(DateTimeFormat) +} + +// ToDateFormat 今天此刻日期 +func (p Pro) ToDateFormat() string { + return p.Time.Format(DateFormat) +} + +// ToTimeFormat 今天此刻时间 +func (p Pro) ToTimeFormat() string { + return p.Time.Format(TimeFormat) +} + +// Timestamp 今天此刻时间戳 +func (p Pro) Timestamp() int64 { + return p.Time.Unix() +} + +// TimestampWithSecond 今天此刻时间戳 +func (p Pro) TimestampWithSecond() int64 { + return p.Time.Unix() +} + +// TimestampWithMillisecond 今天毫秒级时间戳 +func (p Pro) TimestampWithMillisecond() int64 { + return p.Time.UnixNano() / int64(time.Millisecond) +} + +// TimestampWithMicrosecond 今天微秒级时间戳 +func (p Pro) TimestampWithMicrosecond() int64 { + return p.Time.UnixNano() / int64(time.Microsecond) +} + +// TimestampWithNanosecond 今天纳秒级时间戳 +func (p Pro) TimestampWithNanosecond() int64 { + return p.Time.UnixNano() +} diff --git a/yesterday.go b/yesterday.go new file mode 100644 index 0000000..be1cd6c --- /dev/null +++ b/yesterday.go @@ -0,0 +1,17 @@ +package gotime + +import ( + "time" +) + +// Yesterday 昨天 +func Yesterday() Pro { + p := NewPro() + location, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + p.Time = time.Now().Add(time.Hour*8).AddDate(0, 0, -1) + } else { + p.Time = time.Now().In(location).AddDate(0, 0, -1) + } + return p +}