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: Wrong time.AddDate calculation if months' last date is 31 #57139

Closed
ihchristianto opened this issue Dec 7, 2022 · 4 comments
Closed

time: Wrong time.AddDate calculation if months' last date is 31 #57139

ihchristianto opened this issue Dec 7, 2022 · 4 comments
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.

Comments

@ihchristianto
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.19.3 darwin/arm64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/immanuel.christianto/Library/Caches/go-build"
GOENV="/Users/immanuel.christianto/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/immanuel.christianto/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/immanuel.christianto/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/homebrew/Cellar/go/1.19.3/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go/1.19.3/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.19.3"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/immanuel.christianto/Workspace/go-test/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/jc/_p3v_n897w36p97jwnm4splr0000gp/T/go-build1081775705=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

https://go.dev/play/p/CHijIVQtJS4
Try subtracting one month from any month whose last date is 31.
oneMonthBefore := now.AddDate(0, -1, 0)

What did you expect to see?

Now: 2022-01-31 20:20:20 +0700 WIB, One Month Before: 2021-12-31 20:20:20 +0700 WIB
Now: 2022-03-31 20:20:20 +0700 WIB, One Month Before: 2022-02-28 20:20:20 +0700 WIB
Now: 2022-05-31 20:20:20 +0700 WIB, One Month Before: 2022-04-30 20:20:20 +0700 WIB
Now: 2022-07-31 20:20:20 +0700 WIB, One Month Before: 2022-06-30 20:20:20 +0700 WIB
Now: 2022-08-31 20:20:20 +0700 WIB, One Month Before: 2022-07-31 20:20:20 +0700 WIB
Now: 2022-10-31 20:20:20 +0700 WIB, One Month Before: 2022-09-30 20:20:20 +0700 WIB
Now: 2022-12-31 20:20:20 +0700 WIB, One Month Before: 2022-11-30 20:20:20 +0700 WIB

What did you see instead?

Now: 2022-01-31 20:20:20 +0700 WIB, One Month Before: 2021-12-31 20:20:20 +0700 WIB
Now: 2022-03-31 20:20:20 +0700 WIB, One Month Before: 2022-03-03 20:20:20 +0700 WIB
Now: 2022-05-31 20:20:20 +0700 WIB, One Month Before: 2022-05-01 20:20:20 +0700 WIB
Now: 2022-07-31 20:20:20 +0700 WIB, One Month Before: 2022-07-01 20:20:20 +0700 WIB
Now: 2022-08-31 20:20:20 +0700 WIB, One Month Before: 2022-07-31 20:20:20 +0700 WIB
Now: 2022-10-31 20:20:20 +0700 WIB, One Month Before: 2022-10-01 20:20:20 +0700 WIB
Now: 2022-12-31 20:20:20 +0700 WIB, One Month Before: 2022-12-01 20:20:20 +0700 WIB

Hint: instead of going back 1 month, the result seems to subtract the Now date by the number of days in the previous month. Ex, 31 March goes back to 3 March, because February has 28 days. 31-28 = 3

@mengzhuo mengzhuo added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Dec 7, 2022
@ZekeLu
Copy link
Contributor

ZekeLu commented Dec 7, 2022

It works as intended according to the doc https://pkg.go.dev/time#Time.AddDate

AddDate normalizes its result in the same way that Date does, so, for example, adding one month to October 31 yields December 1, the normalized form for November 31.

@bcmills
Copy link
Contributor

bcmills commented Dec 7, 2022

It works as intended according to the doc https://pkg.go.dev/time#Time.AddDate

Agreed: this is working as documented.

“One month before” March 31st would be February 31st, which is not a valid date. There are two possible “reasonable” behaviors: clamp to the last valid date of the month, or compute “February 31st” as 30 days after February 1st. time.AddDate does (and is documented to do) the latter.

@bcmills bcmills closed this as not planned Won't fix, can't repro, duplicate, stale Dec 7, 2022
@bcmills
Copy link
Contributor

bcmills commented Dec 7, 2022

if I subtract and add again the result will not be the same.

That would also be the case if AddDate clamped to the last day of the month: if you say that “one month before” March 31st is February 28th, well, “one month after” February 28th is March 28th, not March 31st.

@ianlancetaylor
Copy link
Contributor

See earlier issue #31145.

@golang golang locked and limited conversation to collaborators Dec 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

6 participants