Skip to content

Commit

Permalink
Add WeekStartTime() function
Browse files Browse the repository at this point in the history
  • Loading branch information
icza committed Aug 29, 2024
1 parent adcb032 commit e8ac847
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
23 changes: 17 additions & 6 deletions timex/timex.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,24 @@ func Diff(a, b time.Time) (year, month, day, hour, min, sec int) {
return
}

// WeekStartTime returns the time instant pointing to the start of the (ISO) week denoted
// by the given timestamp. Weeks are interpreted starting on Monday,
// so the returned instant will be 00:00 UTC of Monday of the designated week.
//
// This function only returns the given week's first day (Monday), because the
// last day of the week is always its first day + 6 days.
func WeekStartTime(t time.Time) time.Time {
t = t.UTC()
if wd := t.Weekday(); wd == time.Sunday {
return t.AddDate(0, 0, -6)
} else {
return t.AddDate(0, 0, -int(wd)+1)
}
}

// WeekStart returns the time instant pointing to the start of the week given
// by its year and ISO Week. Weeks are interpreted starting on Monday,
// so the returned instant will be 00:00 of Monday of the designated week.
// so the returned instant will be 00:00 UTC of Monday of the designated week.
//
// One nice property of this function is that it handles out-of-range weeks nicely.
// That is, if you pass 0 for the week, it will be interpreted as the last week
Expand All @@ -77,11 +92,7 @@ func WeekStart(year, week int) time.Time {
t := time.Date(year, 7, 1, 0, 0, 0, 0, time.UTC)

// Roll back to Monday:
if wd := t.Weekday(); wd == time.Sunday {
t = t.AddDate(0, 0, -6)
} else {
t = t.AddDate(0, 0, -int(wd)+1)
}
t = WeekStartTime(t)

// Difference in weeks:
_, w := t.ISOWeek()
Expand Down
26 changes: 26 additions & 0 deletions timex/timex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,32 @@ func TestDiff(t *testing.T) {
}
}

// ExampleWeekStartTime shows how to use the WeekStartTime() function.
func ExampleWeekStartTime() {
inputs := []struct{ t time.Time }{
{time.Date(2018, 12, 31, 11, 0, 0, 0, time.UTC)},
{time.Date(2019, 1, 1, 11, 0, 0, 0, time.UTC)},
{time.Date(2024, 8, 25, 11, 0, 0, 0, time.UTC)},
{time.Date(2024, 8, 26, 11, 0, 0, 0, time.UTC)},
{time.Date(2024, 8, 29, 11, 0, 0, 0, time.UTC)},
{time.Date(2024, 9, 1, 11, 0, 0, 0, time.UTC)},
{time.Date(2024, 9, 2, 11, 0, 0, 0, time.UTC)},
}
for _, c := range inputs {
fmt.Printf("Week of %v starts on: %v\n",
c.t, WeekStartTime(c.t))
}

// Output:
// Week of 2018-12-31 11:00:00 +0000 UTC starts on: 2018-12-31 11:00:00 +0000 UTC
// Week of 2019-01-01 11:00:00 +0000 UTC starts on: 2018-12-31 11:00:00 +0000 UTC
// Week of 2024-08-25 11:00:00 +0000 UTC starts on: 2024-08-19 11:00:00 +0000 UTC
// Week of 2024-08-26 11:00:00 +0000 UTC starts on: 2024-08-26 11:00:00 +0000 UTC
// Week of 2024-08-29 11:00:00 +0000 UTC starts on: 2024-08-26 11:00:00 +0000 UTC
// Week of 2024-09-01 11:00:00 +0000 UTC starts on: 2024-08-26 11:00:00 +0000 UTC
// Week of 2024-09-02 11:00:00 +0000 UTC starts on: 2024-09-02 11:00:00 +0000 UTC
}

// ExampleWeekStart shows how to use the WeekStart() function.
func ExampleWeekStart() {
inputs := []struct{ year, week int }{
Expand Down

0 comments on commit e8ac847

Please sign in to comment.