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: MarshalBinary fails on valid Time #39616
Comments
Thank you for raising this issue. Before we can investigate could you please update your sample code to check all errors and verify that the issues is still present. |
I updated the sample code with error checks and better output. The problem still occurs. |
0001 ad is not within the range that time.Time supports, please try https://play.golang.org/p/7JicBQHKeeq |
Please point me to the documentation that states what is the minimum supported value. According to the documentation for So for this example using
The cut off between invalid and valid times seems to be at: |
Thank you for correcting me. I agree that parse suggests it accepts a 10000 year range. The closest I can find to the range of values that parse can return comes from https://golang.org/pkg/time/#Time.UnixNano. I cannot seem to find any documentation other than this. I’m having trouble understanding your original question. This is my fault, I’m just not understanding what you are saying. Is it possible for you to restate your problem in the form of a goal “I need to x, do to x I tried to y”? |
Sure. No problem. I have 2 use cases:
For both cases local timezone is |
If I'm reading this right, the basic problem is that https://play.golang.org/p/JcLg4diDncx package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse(time.RFC3339, "1880-01-01T00:00:00Z")
if err != nil {
fmt.Println("Failed to parse time", err)
}
loc, err := time.LoadLocation("US/Eastern")
if err != nil {
fmt.Println("Failed to load location", err)
}
t2 := t.In(loc)
fmt.Println("Zero Eastern:", t2)
b, err := t2.MarshalBinary()
if err != nil {
fmt.Println("Failed to marshal", err)
} else {
fmt.Println("Got bytes", b)
}
} |
Yes, the main crux is Some Info: Part of the problem is with changing the time zone for values before time zones existed. Which looks to be based on when US railways adopted time zones: https://en.wikipedia.org/wiki/Time_zone#cite_ref-8 (Adding the above to the documentation for I guess the question of: Should we maintain historic accuracy or expected behavior? |
We return |
Makes sense - that's what I expected is the case. |
So should I implement |
That would fix my use case. |
I am currently working on this issue. As what I asked, I was refactoring |
I would be OK with using timeBinaryVerison 2 to represent timezone seconds when required. We should still use version in the normal case. |
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
Change https://golang.org/cl/243402 mentions this issue: |
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
If the time is in 'LMT' and has fractional minute, then `MarshalBinary()` and `UnmarshalBinary()` will encode/decode the time in `timeBinaryVersionV2` in which the fractional minute is at bit 15 and 16, and presented in seconds. Fixes golang#39616
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Call
In
on a zero valuetime.Time
creates in valid time when the result would be before the zero time.https://play.golang.org/p/BJQVBcW9Rcj
What did you expect to see?
The zero value time would have its time zone set to the specified timezone yet still be the zero value date.
For Example:
Setting
0001-01-01 00:00 UTC
toEDT
should return0001-01-01 00:00 EDT
or return an error if the value is outside the range (which in this case it is)Using
zeroTime.After(newTime)
should returntrue
or some other mechanism to check the time is valid should exist.What did you see instead?
A time value before the range was returned with an invalid time zone
0000-12-31 19:03:58 -0456 LMT
.Attempting to compare the result against the
zero
time usingAfter
does not function aszeroTime.After(newTime)
andnewTime.After(zeroTime)
both return false so you can have a false positive that the time is valid.Also the resulting time value prevents
MarshalBinary
from workingThe text was updated successfully, but these errors were encountered: