From 9203c3719fd35edfc0e19c9a360a351176981dd8 Mon Sep 17 00:00:00 2001 From: charlie <3140647@qq.com> Date: Wed, 9 Nov 2022 17:16:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=8E=86=E7=9B=B8=E5=85=B3=E8=AE=A1?= =?UTF-8?q?=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- calendar/calendar.go | 210 ++++++++++++++++++++++++++++++++++++++ calendar/calendar_test.go | 38 +++++++ calendar/creator.go | 40 ++++++++ calendar/output.go | 74 ++++++++++++++ calendar/output_test.go | 19 ++++ 5 files changed, 381 insertions(+) create mode 100644 calendar/calendar.go create mode 100644 calendar/calendar_test.go create mode 100644 calendar/creator.go create mode 100644 calendar/output.go create mode 100644 calendar/output_test.go diff --git a/calendar/calendar.go b/calendar/calendar.go new file mode 100644 index 0000000..442718a --- /dev/null +++ b/calendar/calendar.go @@ -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 +} diff --git a/calendar/calendar_test.go b/calendar/calendar_test.go new file mode 100644 index 0000000..9fb11d2 --- /dev/null +++ b/calendar/calendar_test.go @@ -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)) +} diff --git a/calendar/creator.go b/calendar/creator.go new file mode 100644 index 0000000..60a7f07 --- /dev/null +++ b/calendar/creator.go @@ -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), + } +} diff --git a/calendar/output.go b/calendar/output.go new file mode 100644 index 0000000..2ca666d --- /dev/null +++ b/calendar/output.go @@ -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()) +} diff --git a/calendar/output_test.go b/calendar/output_test.go new file mode 100644 index 0000000..d76a253 --- /dev/null +++ b/calendar/output_test.go @@ -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()) +}