diff --git a/datetime/period.go b/datetime/period.go new file mode 100644 index 0000000..03e3a5c --- /dev/null +++ b/datetime/period.go @@ -0,0 +1,41 @@ +package datetime + +import "time" + +type Period struct { + Begin time.Time `json:"start" yaml:"start"` + End time.Time `json:"end" yaml:"end"` +} + +const maxNsec = 999999999 + +func NewPeriod(a, b time.Time) Period { + return Period{Begin: StartOfDay(a), End: EndOfDay(b)} +} + +func StartOfDay(t time.Time) time.Time { + return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC) +} + +func EndOfDay(t time.Time) time.Time { + return time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, maxNsec, time.UTC) +} + +func MonthOf(t time.Time) Period { + var ( + begin = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.UTC) + finalDay = time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, time.UTC).Day() + end = time.Date(t.Year(), t.Month(), finalDay, 23, 59, 59, maxNsec, time.UTC) + ) + + return Period{Begin: begin, End: end} +} + +func PreviousMonthOf(t time.Time) Period { + return MonthOf(t.AddDate(0, -1, 0)) +} + +func (p Period) Within(o Period) bool { + return (p.Begin.Equal(o.Begin) || p.Begin.After(o.Begin)) && + (p.End.Equal(o.End) || p.End.Before(o.End)) +} diff --git a/datetime/period_test.go b/datetime/period_test.go new file mode 100644 index 0000000..b7e81a0 --- /dev/null +++ b/datetime/period_test.go @@ -0,0 +1,47 @@ +package datetime_test + +import ( + "testing" + "time" + + "github.com/blue-health/blue-go-toolbox/datetime" + "github.com/stretchr/testify/require" +) + +func TestPreviousMonthOf(t *testing.T) { + testCases := []struct { + in time.Time + out datetime.Period + }{ + {in: time.Date(2022, time.July, 1, 0, 0, 0, 0, time.UTC), out: datetime.Period{ + Begin: time.Date(2022, time.June, 1, 0, 0, 0, 0, time.UTC), + End: time.Date(2022, time.June, 30, 23, 59, 59, 999999999, time.UTC), + }}, + {in: time.Date(2022, time.August, 1, 0, 0, 0, 0, time.UTC), out: datetime.Period{ + Begin: time.Date(2022, time.July, 1, 0, 0, 0, 0, time.UTC), + End: time.Date(2022, time.July, 31, 23, 59, 59, 999999999, time.UTC), + }}, + {in: time.Date(2022, time.September, 3, 0, 0, 0, 0, time.UTC), out: datetime.Period{ + Begin: time.Date(2022, time.August, 1, 0, 0, 0, 0, time.UTC), + End: time.Date(2022, time.August, 31, 23, 59, 59, 999999999, time.UTC), + }}, + {in: time.Date(2022, time.September, 15, 0, 0, 0, 0, time.UTC), out: datetime.Period{ + Begin: time.Date(2022, time.August, 1, 0, 0, 0, 0, time.UTC), + End: time.Date(2022, time.August, 31, 23, 59, 59, 999999999, time.UTC), + }}, + {in: time.Date(2022, time.September, 30, 0, 0, 0, 0, time.UTC), out: datetime.Period{ + Begin: time.Date(2022, time.August, 1, 0, 0, 0, 0, time.UTC), + End: time.Date(2022, time.August, 31, 23, 59, 59, 999999999, time.UTC), + }}, + {in: time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC), out: datetime.Period{ + Begin: time.Date(2022, time.December, 1, 0, 0, 0, 0, time.UTC), + End: time.Date(2022, time.December, 31, 23, 59, 59, 999999999, time.UTC), + }}, + } + + for _, c := range testCases { + t.Run(c.in.Format(time.RFC1123), func(t *testing.T) { + require.Equal(t, c.out, datetime.PreviousMonthOf(c.in)) + }) + } +} diff --git a/datetime/time.go b/datetime/time.go deleted file mode 100644 index 63ad5da..0000000 --- a/datetime/time.go +++ /dev/null @@ -1,25 +0,0 @@ -package datetime - -import "time" - -type Period struct { - Begin, End time.Time -} - -func StartOfDay(t time.Time) time.Time { - return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC) -} - -func EndOfDay(t time.Time) time.Time { - return time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 0, time.UTC) -} - -func MonthOf(t time.Time) Period { - var ( - begin = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.UTC) - finalDay = time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, time.UTC).Day() - end = time.Date(t.Year(), t.Month(), finalDay, 23, 59, 59, 0, time.UTC) - ) - - return Period{Begin: begin, End: end} -} diff --git a/go.mod b/go.mod index a25aaf8..3ade9bc 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/microcosm-cc/bluemonday v1.0.20 github.com/stretchr/testify v1.8.0 golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 - google.golang.org/genproto v0.0.0-20220909194730-69f6226f97e5 + google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f gopkg.in/guregu/null.v4 v4.0.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -48,7 +48,7 @@ require ( golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect golang.org/x/sync v0.0.0-20220907140024-f12130a52804 // indirect - golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect + golang.org/x/sys v0.0.0-20220913175220-63ea55921009 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/api v0.95.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index d217126..f768e44 100644 --- a/go.sum +++ b/go.sum @@ -476,8 +476,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho= -golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220913175220-63ea55921009 h1:PuvuRMeLWqsf/ZdT1UUZz0syhioyv1mzuFZsXs4fvhw= +golang.org/x/sys v0.0.0-20220913175220-63ea55921009/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -681,8 +681,8 @@ google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljW google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220909194730-69f6226f97e5 h1:ngtP8S8JkBWfJACT9cmj5eTkS9tIWPQI5leBz/7Bq/c= -google.golang.org/genproto v0.0.0-20220909194730-69f6226f97e5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f h1:wwbo0UziciPT4Dsca+bmplW53QNAl7tiUOw7FfAcsf8= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=