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: unable to parse UTC leap seconds #8728

Closed
aecolley opened this issue Sep 14, 2014 · 8 comments

Comments

Projects
None yet
10 participants
@aecolley
Copy link

commented Sep 14, 2014

What does 'go version' print?

go version go1.3.1 linux/amd64

What steps reproduce the problem?

Attempting to parse any valid leap second, such as "2005-12-31T23:59:60Z".
http://play.golang.org/p/lBYHT8mwbb

What happened?

parse error: parsing time "2005-12-31T23:59:60Z": second out of range

What should have happened instead?

parsed as: 2005-12-31T23:59:60Z

Please provide any additional information below.

http://golang.org/src/pkg/time/format.go has the immediate bug at lines 818-822:
  case stdSecond, stdZeroSecond:
    sec, value, err = getnum(value, std == stdZeroSecond)
    if sec < 0 || 60 <= sec {
      rangeErrString = "second"
    }

It seems that there's a fundamental restriction in the time package, where it repeats
the expensive POSIX mistake of assuming that you can ignore leap seconds if you're not
doing high-precision radio astronomy. Since leap seconds don't go away just because you
can't represent them in the most convenient time datatype, this makes the time package
useless for programs that are supposed to continue to run without crashing during a leap
second.

Suggested fixes:
1. Full support for conversion between monotonic counter (TAI) <=> wall time (UTC)
<=> POSIX time_t. The API is already flexible enough for this, but the
implementation would need to become aware of leap seconds.
2. Change the package documentation so it gives fair warning that "UTC"
doesn't mean real UTC, but has undefined behavior for leap seconds.
3. Abolish leap seconds. There may be politics involved.
4. Declare this behavior "working as intended". Make it someone else's problem
to cope with the next leap-second production crisis (scheduled for 2015). Deplore the
horrible hacks they perpetrate to keep the site up, eg:
http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html
@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Sep 14, 2014

Comment 1:

Labels changed: added repo-main, release-none.

@aecolley aecolley added new labels Sep 14, 2014

@bradfitz bradfitz removed the new label Dec 18, 2014

@rsc rsc added this to the Unplanned milestone Apr 10, 2015

@rsc rsc removed release-none labels Apr 10, 2015

@rickb777

This comment has been minimized.

Copy link

commented Nov 24, 2015

Has this been kicked off into the long grass?

It's a shame it isn't getting some attention (especially in view of Java8 having finally sorted out the Java implementation https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html).

@PaluMacil

This comment has been minimized.

Copy link

commented Jan 3, 2017

This is somewhat related to Cloudflare's outtage this year: How and why the leap second affected Cloudflare DNS

@JohnSauter

This comment has been minimized.

Copy link

commented Jan 3, 2017

It would not be difficult to support leap seconds. See https://commons.wikimedia.org/wiki/File:Avoid_Using_POSIX_time_t_for_Telling_Time.pdf for some suggestions on how.

@mj1856

This comment has been minimized.

Copy link

commented Jan 5, 2017

@PaluMacil - Not really. There was no parsing of ":60" involved in that particular problem.

@mj1856

This comment has been minimized.

Copy link

commented Jan 5, 2017

Note that not very many other languages support parsing :60 in the seconds field. For example, JavaScript returns an Invalid Date, and .NET throws a FormatException. I'm sure others give similar errors.

Those that do stub it for :59, such as Java 8's new time API, which describes it's handling of leap seconds here: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#parsedLeapSecond--

Ultimately, the problem is that most internal data structures store a number of units since some epoch, and don't track a table of leap seconds. Doing so would come at a performance and maintenance cost that's usually not worth it.

Unix Time, for example, is explicitly the number of non-leap seconds since 1970-01-01T00:00:00Z.

@mj1856

This comment has been minimized.

Copy link

commented Jan 5, 2017

Also note that #15247 already documented that leap seconds are not accounted for in calculations. I see no reason that parsing should be any different.

@ALTree ALTree modified the milestones: Go1.9, Unplanned Feb 1, 2017

@ALTree ALTree added the NeedsDecision label Feb 1, 2017

@rsc

This comment has been minimized.

Copy link
Contributor

commented Feb 2, 2017

The options here are either (1) parse seconds=60 as seconds=59, or (2) continue to return an error. Given that we've returned an error this far with minimal fallout and also that .NET and even JavaScript (not exactly known as a picky language!) return errors, I am comfortable continuing to return an error.

@rsc rsc closed this Feb 2, 2017

@golang golang locked and limited conversation to collaborators Feb 2, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.