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

proposal: time: add IsUnixEpoch method to test whether a time is the Unix epoch #46974

Closed
joshbradshaw11 opened this issue Jun 29, 2021 · 5 comments
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@joshbradshaw11
Copy link

$ go version

go version go1.15.6 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What did you do?

This is just an opinion, but I think that the the time library should provide a simpler method for getting the Epoch time.

I was surprised by this:

t := time.Unix(int64(0), 0)
log.Println("Time is ", t.String())
log.Println("Is time zero: ", t.IsZero())
log.Println("Is time epoch: ", t == time.Unix(int64(0), 0))
Time is  1969-12-31 19:00:00 -0500 EST
Is time zero:  false
Is time epoch:  true

Upon further inspection I realized that I needed to do time.Unix(0, 0).UTC() to get the epoch value because time.Unix() is timezone aware. Given that the API already has a time.isZero() method, I think there should be a method for fetching the environment's epoch value directly, without using a parsing method or a timezone aware method.

@ianlancetaylor
Copy link
Contributor

Note that the time package's epoch is simply 1-1-1 00:00:00 UTC which is not coincidentally the zero value of time.Time. You are talking about the Unix epoch, which the time package supports via the time.Time methods Unix, UnixNano, UnixMilli, and UnixMicro (the latter two new in 1.17) and the Unix, UnixMilli, and UnixMicro functions (again the latter two are new in 1.17). Other than those functions and methods the Unix epoch is unimportant to the time package.

You say an Epoch method but I'm guessing that in Go terminology you mean an Epoch function. Specifically, you suggest

// UnixEpoch returns the start of the Unix epoch in UTC.
func UnixEpoch() time.Time {
    return time.Unix(0, 0).UTC()
}

Is that correct?

If that is correct, it's not clear to me that that is useful enough by itself. How often does this come up? When do you need the Unix epoch value as a time.Time?

@seankhliao seankhliao changed the title Suggestion: The time library should include an Epoch() method proposal: time: add UnixEpoch to rstart of the Unix epoch in UTC Jun 30, 2021
@gopherbot gopherbot added this to the Proposal milestone Jun 30, 2021
@seankhliao seankhliao added WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. and removed Proposal labels Jun 30, 2021
@joshbradshaw11
Copy link
Author

joshbradshaw11 commented Jul 15, 2021

Note that the time package's epoch is simply 1-1-1 00:00:00 UTC which is not coincidentally the zero value of time.Time. You are talking about the Unix epoch, which the time package supports via the time.Time methods Unix, UnixNano, UnixMilli, and UnixMicro (the latter two new in 1.17) and the Unix, UnixMilli, and UnixMicro functions (again the latter two are new in 1.17). Other than those functions and methods the Unix epoch is unimportant to the time package.

You say an Epoch method but I'm guessing that in Go terminology you mean an Epoch function. Specifically, you suggest

// UnixEpoch returns the start of the Unix epoch in UTC.
func UnixEpoch() time.Time {
    return time.Unix(0, 0).UTC()
}

Is that correct?

If that is correct, it's not clear to me that that is useful enough by itself. How often does this come up? When do you need the Unix epoch value as a time.Time?

I encountered this problem while writing an embedded application for a 3D printer. We manufacture separate resin cartridges for these 3D printers, and these cartridges have little EEPROMs onboard that store usage statistics. One of the statistics we need to store is the date that the cartridge was first used, because the material has a short shelf life. We store this value in the units UnixEpoch_s. We use 0 / unix epoch as the sentinel value to tell us that this field is uninitialized.

I made a bug in this case by using time.IsZero() as opposed to a comparison with time.Unix(0, 0).UTC().

Given that time.IsZero already exists, I think that it would be very reasonable to provide an time.isEpoch function as a convenience for people who write software that interoperates with other systems that do use the unix epoch as the zero time value. I think that listing isZero and isUnixEpoch alongside each other in the library documentation will help draw people's attention to this particular design decision in go to use 1-1-1 00:00:00 UTC, which differs from many other business oriented programming languages.

@ianlancetaylor ianlancetaylor changed the title proposal: time: add UnixEpoch to rstart of the Unix epoch in UTC proposal: time: add IsUnixEpoch method to test whether a time is the Unix epoch Jul 15, 2021
@ianlancetaylor
Copy link
Contributor

Thanks for the example. Honestly that seems kind of specific to me. I don't see why many people would use the suggested IsUnixEpoch method, and of course it is trivial to provide this outside the standard library (https://golang.org/doc/faq#x_in_std). I agree that this is something that people using the time package have to learn, but it is already clearly documented, and once you learn it you will remember it. Even the documentation for IsZero refers to specifically to "year 1".

@joshbradshaw11
Copy link
Author

My final comment is that the IsZero method never should have existed because time is an affine space type. There's a reason every other language uses the word epoch

@ianlancetaylor
Copy link
Contributor

The IsZero method exists because all Go types must have a zero value, and it can be useful to test whether a time.Time value was never initialized. Perhaps it was a mistake, but it's too late now.

@golang golang locked and limited conversation to collaborators Jul 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

4 participants