mirror of
https://github.com/charlienet/go-mixed.git
synced 2025-07-17 08:02:40 +08:00
日历相关计算
This commit is contained in:
210
calendar/calendar.go
Normal file
210
calendar/calendar.go
Normal file
@ -0,0 +1,210 @@
|
||||
package calendar
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var WeekStartDay time.Weekday = time.Sunday
|
||||
|
||||
type Calendar struct {
|
||||
time.Time
|
||||
weekStartsAt time.Weekday
|
||||
}
|
||||
|
||||
func BeginningOfMinute() Calendar {
|
||||
return Create(time.Now()).BeginningOfMinute()
|
||||
}
|
||||
|
||||
func BeginningOfHour() Calendar {
|
||||
return Create(time.Now()).BeginningOfHour()
|
||||
}
|
||||
|
||||
func BeginningOfDay() Calendar {
|
||||
return Create(time.Now()).BeginningOfDay()
|
||||
}
|
||||
|
||||
func BeginningOfWeek() Calendar {
|
||||
return Create(time.Now()).BeginningOfWeek()
|
||||
}
|
||||
|
||||
func BeginningOfMonth() Calendar {
|
||||
return Create(time.Now()).BeginningOfMonth()
|
||||
}
|
||||
|
||||
func BeginningOfQuarter() Calendar {
|
||||
return Create(time.Now()).BeginningOfQuarter()
|
||||
}
|
||||
|
||||
func BeginningOfYear() Calendar {
|
||||
return Create(time.Now()).BeginningOfYear()
|
||||
}
|
||||
|
||||
func EndOfMinute() Calendar {
|
||||
return Create(time.Now()).EndOfMinute()
|
||||
}
|
||||
|
||||
func EndOfHour() Calendar {
|
||||
return Create(time.Now()).EndOfHour()
|
||||
}
|
||||
|
||||
func EndOfDay() Calendar {
|
||||
return Create(time.Now()).EndOfDay()
|
||||
}
|
||||
|
||||
func EndOfWeek() Calendar {
|
||||
return Create(time.Now()).EndOfWeek()
|
||||
}
|
||||
|
||||
func EndOfMonth() Calendar {
|
||||
return Create(time.Now()).EndOfMonth()
|
||||
}
|
||||
|
||||
func EndOfQuarter() Calendar {
|
||||
return Create(time.Now()).EndOfQuarter()
|
||||
}
|
||||
|
||||
func EndOfYear() Calendar {
|
||||
return Create(time.Now()).EndOfYear()
|
||||
}
|
||||
|
||||
func (c Calendar) WeekStartsAt(day time.Weekday) Calendar {
|
||||
return Calendar{
|
||||
Time: c.Time,
|
||||
weekStartsAt: day,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) BeginningOfMinute() Calendar {
|
||||
return Calendar{Time: c.Truncate(time.Minute)}
|
||||
|
||||
}
|
||||
|
||||
func (c Calendar) BeginningOfHour() Calendar {
|
||||
y, m, d := c.Date()
|
||||
return Calendar{
|
||||
Time: time.Date(y, m, d, c.Hour(), 0, 0, 0, c.Location()),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) BeginningOfDay() Calendar {
|
||||
y, m, d := c.Date()
|
||||
|
||||
return Calendar{
|
||||
Time: time.Date(y, m, d, 0, 0, 0, 0, c.Location()),
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) BeginningOfWeek() Calendar {
|
||||
t := c.BeginningOfDay()
|
||||
weekday := int(t.Weekday())
|
||||
|
||||
if c.weekStartsAt != time.Sunday {
|
||||
weekStartDayInt := int(c.weekStartsAt)
|
||||
|
||||
if weekday < weekStartDayInt {
|
||||
weekday = weekday + 7 - weekStartDayInt
|
||||
} else {
|
||||
weekday = weekday - weekStartDayInt
|
||||
}
|
||||
}
|
||||
|
||||
return Calendar{
|
||||
Time: t.AddDate(0, 0, -weekday),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) BeginningOfMonth() Calendar {
|
||||
y, m, _ := c.Date()
|
||||
|
||||
return Calendar{
|
||||
Time: time.Date(y, m, 1, 0, 0, 0, 0, c.Location()),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) BeginningOfQuarter() Calendar {
|
||||
month := c.BeginningOfMonth()
|
||||
offset := (int(month.Month()) - 1) % 3
|
||||
|
||||
return Calendar{
|
||||
Time: month.AddDate(0, -offset, 0),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) BeginningOfYear() Calendar {
|
||||
y, _, _ := c.Date()
|
||||
|
||||
return Calendar{
|
||||
Time: time.Date(y, time.January, 1, 0, 0, 0, 0, c.Location()),
|
||||
weekStartsAt: c.weekStartsAt}
|
||||
}
|
||||
|
||||
func (c Calendar) EndOfMinute() Calendar {
|
||||
n := c.BeginningOfMinute()
|
||||
|
||||
return Calendar{
|
||||
Time: n.Add(time.Minute - time.Nanosecond),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) EndOfHour() Calendar {
|
||||
n := c.BeginningOfHour()
|
||||
|
||||
return Calendar{
|
||||
Time: n.Add(time.Hour - time.Nanosecond),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) EndOfDay() Calendar {
|
||||
y, m, d := c.Date()
|
||||
|
||||
return Calendar{
|
||||
Time: time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), c.Location()),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) EndOfWeek() Calendar {
|
||||
n := c.BeginningOfWeek()
|
||||
|
||||
return Calendar{
|
||||
Time: n.AddDate(0, 0, 7).Add(-time.Nanosecond),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) EndOfMonth() Calendar {
|
||||
n := c.BeginningOfMonth()
|
||||
|
||||
return Calendar{
|
||||
Time: n.AddDate(0, 1, 0).Add(-time.Nanosecond),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) EndOfQuarter() Calendar {
|
||||
n := c.BeginningOfQuarter()
|
||||
|
||||
return Calendar{
|
||||
Time: n.AddDate(0, 3, 0).Add(-time.Nanosecond),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) EndOfYear() Calendar {
|
||||
n := c.BeginningOfYear()
|
||||
|
||||
return Calendar{
|
||||
Time: n.AddDate(1, 0, 0).Add(-time.Nanosecond),
|
||||
weekStartsAt: c.weekStartsAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Calendar) ToTime() time.Time {
|
||||
return c.Time
|
||||
}
|
38
calendar/calendar_test.go
Normal file
38
calendar/calendar_test.go
Normal file
@ -0,0 +1,38 @@
|
||||
package calendar_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/charlienet/go-mixed/calendar"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var format = "2006-01-02 15:04:05.999999999"
|
||||
|
||||
func TestToday(t *testing.T) {
|
||||
t.Log(calendar.Today())
|
||||
}
|
||||
|
||||
func TestBeginningOf(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
|
||||
n := time.Date(2022, 11, 9, 14, 28, 34, 123456789, time.UTC)
|
||||
a.Equal("2022-11-06 00:00:00", calendar.Create(n).BeginningOfWeek().String())
|
||||
a.Equal("2022-11-07 00:00:00", calendar.Create(n).WeekStartsAt(time.Monday).BeginningOfWeek().Format(format))
|
||||
a.Equal("2022-11-09 14:00:00", calendar.Create(n).BeginningOfHour().Format(format))
|
||||
a.Equal("2022-11-01 00:00:00", calendar.Create(n).BeginningOfMonth().Format(format))
|
||||
a.Equal("2022-10-01 00:00:00", calendar.Create(n).BeginningOfQuarter().Format(format))
|
||||
}
|
||||
|
||||
func TestEndOf(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
|
||||
n := time.Date(2022, 11, 9, 14, 28, 34, 123456789, time.UTC)
|
||||
a.Equal("2022-11-09 14:28:59.999999999", calendar.Create(n).EndOfMinute().Format(format))
|
||||
a.Equal("2022-11-09 14:59:59.999999999", calendar.Create(n).EndOfHour().Format(format))
|
||||
a.Equal("2022-11-09 23:59:59.999999999", calendar.Create(n).EndOfDay().Format(format))
|
||||
a.Equal("2022-11-30 23:59:59.999999999", calendar.Create(n).EndOfMonth().Format(format))
|
||||
a.Equal("2022-12-31 23:59:59.999999999", calendar.Create(n).EndOfQuarter().Format(format))
|
||||
a.Equal("2022-12-31 23:59:59.999999999", calendar.Create(n).EndOfYear().Format(format))
|
||||
}
|
40
calendar/creator.go
Normal file
40
calendar/creator.go
Normal file
@ -0,0 +1,40 @@
|
||||
package calendar
|
||||
|
||||
import "time"
|
||||
|
||||
func Now() Calendar {
|
||||
return Create(time.Now())
|
||||
}
|
||||
|
||||
func Today() Calendar {
|
||||
return Now().BeginningOfDay()
|
||||
}
|
||||
|
||||
func Create(t time.Time) Calendar {
|
||||
return Calendar{
|
||||
Time: t,
|
||||
weekStartsAt: WeekStartDay,
|
||||
}
|
||||
}
|
||||
|
||||
func CreateFromTimestamp(timestamp int64) Calendar {
|
||||
return Create(time.Unix(timestamp, 0))
|
||||
}
|
||||
|
||||
func CreateFromTimestampMilli(timestamp int64) Calendar {
|
||||
return Create(time.Unix(timestamp/1e3, (timestamp%1e3)*1e6))
|
||||
}
|
||||
|
||||
func CreateFromTimestampMicro(timestamp int64) Calendar {
|
||||
return Create(time.Unix(timestamp/1e6, (timestamp%1e6)*1e3))
|
||||
}
|
||||
|
||||
func CreateFromTimestampNano(timestamp int64) Calendar {
|
||||
return Create(time.Unix(timestamp/1e9, timestamp%1e9))
|
||||
}
|
||||
|
||||
func create(year, month, day, hour, minute, second, nanosecond int) Calendar {
|
||||
return Calendar{
|
||||
Time: time.Date(year, time.Month(month), day, hour, minute, second, nanosecond, time.Local),
|
||||
}
|
||||
}
|
74
calendar/output.go
Normal file
74
calendar/output.go
Normal file
@ -0,0 +1,74 @@
|
||||
package calendar
|
||||
|
||||
import "time"
|
||||
|
||||
// 布局模板常量
|
||||
const (
|
||||
ANSICLayout = time.ANSIC
|
||||
UnixDateLayout = time.UnixDate
|
||||
RubyDateLayout = time.RubyDate
|
||||
RFC822Layout = time.RFC822
|
||||
RFC822ZLayout = time.RFC822Z
|
||||
RFC850Layout = time.RFC850
|
||||
RFC1123Layout = time.RFC1123
|
||||
RFC1123ZLayout = time.RFC1123Z
|
||||
RssLayout = time.RFC1123Z
|
||||
KitchenLayout = time.Kitchen
|
||||
RFC2822Layout = time.RFC1123Z
|
||||
CookieLayout = "Monday, 02-Jan-2006 15:04:05 MST"
|
||||
RFC3339Layout = "2006-01-02T15:04:05Z07:00"
|
||||
RFC3339MilliLayout = "2006-01-02T15:04:05.999Z07:00"
|
||||
RFC3339MicroLayout = "2006-01-02T15:04:05.999999Z07:00"
|
||||
RFC3339NanoLayout = "2006-01-02T15:04:05.999999999Z07:00"
|
||||
ISO8601Layout = "2006-01-02T15:04:05-07:00"
|
||||
ISO8601MilliLayout = "2006-01-02T15:04:05.999-07:00"
|
||||
ISO8601MicroLayout = "2006-01-02T15:04:05.999999-07:00"
|
||||
ISO8601NanoLayout = "2006-01-02T15:04:05.999999999-07:00"
|
||||
RFC1036Layout = "Mon, 02 Jan 06 15:04:05 -0700"
|
||||
RFC7231Layout = "Mon, 02 Jan 2006 15:04:05 GMT"
|
||||
DayDateTimeLayout = "Mon, Jan 2, 2006 3:04 PM"
|
||||
DateTimeLayout = "2006-01-02 15:04:05"
|
||||
DateTimeMilliLayout = "2006-01-02 15:04:05.999"
|
||||
DateTimeMicroLayout = "2006-01-02 15:04:05.999999"
|
||||
DateTimeNanoLayout = "2006-01-02 15:04:05.999999999"
|
||||
ShortDateTimeLayout = "20060102150405"
|
||||
ShortDateTimeMilliLayout = "20060102150405.999"
|
||||
ShortDateTimeMicroLayout = "20060102150405.999999"
|
||||
ShortDateTimeNanoLayout = "20060102150405.999999999"
|
||||
DateLayout = "2006-01-02"
|
||||
DateMilliLayout = "2006-01-02.999"
|
||||
DateMicroLayout = "2006-01-02.999999"
|
||||
DateNanoLayout = "2006-01-02.999999999"
|
||||
ShortDateLayout = "20060102"
|
||||
ShortDateMilliLayout = "20060102.999"
|
||||
ShortDateMicroLayout = "20060102.999999"
|
||||
ShortDateNanoLayout = "20060102.999999999"
|
||||
TimeLayout = "15:04:05"
|
||||
TimeMilliLayout = "15:04:05.999"
|
||||
TimeMicroLayout = "15:04:05.999999"
|
||||
TimeNanoLayout = "15:04:05.999999999"
|
||||
ShortTimeLayout = "150405"
|
||||
ShortTimeMilliLayout = "150405.999"
|
||||
ShortTimeMicroLayout = "150405.999999"
|
||||
ShortTimeNanoLayout = "150405.999999999"
|
||||
)
|
||||
|
||||
func (c Calendar) String() string {
|
||||
return c.ToDateTimeString()
|
||||
}
|
||||
|
||||
func (c Calendar) ToDateTimeString() string {
|
||||
return c.Format(DateTimeLayout)
|
||||
}
|
||||
|
||||
func (c Calendar) ToDateTimeInt() int {
|
||||
return c.ToShortDateInt()*1000000 + c.Hour()*10000 + c.Minute()*100 + c.Second()
|
||||
}
|
||||
|
||||
func (c Calendar) ToShortDateInt() int {
|
||||
return c.Year()*10000 + int(c.Month())*100 + c.Day()
|
||||
}
|
||||
|
||||
func (c Calendar) ToMonthInt() int {
|
||||
return c.Year()*100 + int(c.Month())
|
||||
}
|
19
calendar/output_test.go
Normal file
19
calendar/output_test.go
Normal file
@ -0,0 +1,19 @@
|
||||
package calendar_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/charlienet/go-mixed/calendar"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDayInt(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
n := time.Date(2022, 11, 9, 14, 28, 34, 123456789, time.UTC)
|
||||
|
||||
assert.Equal(20221109, calendar.Create(n).ToShortDateInt())
|
||||
assert.Equal(202211, calendar.Create(n).ToMonthInt())
|
||||
assert.Equal(20221109142834, calendar.Create(n).ToDateTimeInt())
|
||||
}
|
Reference in New Issue
Block a user