Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time: add AddDateX more attention to months then AddDate #48862

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/time/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,37 @@ func (t Time) AddDate(years int, months int, days int) Time {
return Date(year+years, month+Month(months), day+days, hour, min, sec, int(t.nsec()), t.Location())
}

// AddDateX returns the time more attention to months then AddDate.
// For example, AddDateX(0, 1, 0) applied to 2021-08-31
// will returns 2021-09-30.
// Because in most cases, the expectation is the change of months,
// so, process day after process year and month
//
// AddDateX if you want to normalizes the result like AddDate,
// You can set the optional param normalizes equal to true,
// It will be the same as the result of the function AddDate.
func (t Time) AddDateX(years int, months int, days int, normalizes ...bool) Time {
year, month, day := t.Date()
hour, min, sec := t.Clock()

if len(normalizes) > 0 && normalizes[0] == true {
return Date(year+years, month+Month(months), day+days, hour, min, sec, int(t.nsec()), t.Location())
}

// Normalize month, overflowing into year.
m := int(month+Month(months)) - 1
year, m = norm(year+years, m, 12)
month = Month(m) + 1

if lDay := daysIn(month, year); day > lDay {
// If the desired month does not have this day,
// temporarily set the day as the maximum day of the desired month,
// and then process the param days.
day = lDay
}
return Date(year, month, day+days, hour, min, sec, int(t.nsec()), t.Location())
}

const (
secondsPerMinute = 60
secondsPerHour = 60 * secondsPerMinute
Expand Down
21 changes: 21 additions & 0 deletions src/time/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,27 @@ func TestAddDate(t *testing.T) {
}
}

var addDateXTests = []struct {
years, months, days int
}{
{4, 6, 0},
{3, 18, 0},
{5, -6, 0},
}

func TestAddDateX(t *testing.T) {
t0 := Date(2021, 10, 31, 16, 8, 8, 0, UTC)
t1 := Date(2026, 4, 30, 16, 8, 8, 0, UTC)
for _, at := range addDateXTests {
time := t0.AddDateX(at.years, at.months, at.days)
if !time.Equal(t1) {
t.Errorf("AddDateX(%d, %d, %d) = %v, want %v",
at.years, at.months, at.days,
time, t1)
}
}
}

var daysInTests = []struct {
year, month, di int
}{
Expand Down