Skip to content

times.toDateTime buggy on 29th, 30th and 31th of each month #13558

Closed
@timotheecour

Description

@timotheecour

times.toDateTime has leapYear bug that creeps up 1 day every 4y; it can cause damage/hard to track bugs in production so should be fixed.

Example

go back in time february 29 2020
nim c -r tests/stdlib/ttimes.nim

Current Output

2020-02-29T10:50:44.9992311Z ttimes.nim(476)          ttimes
2020-02-29T10:50:44.9992640Z times.nim(2433)          parse
2020-02-29T10:50:44.9993008Z times.nim(2412)          parse
2020-02-29T10:50:44.9993344Z times.nim(2287)          toDateTime
2020-02-29T10:50:44.9993757Z times.nim(1814)          raiseParseException
2020-02-29T10:50:44.9994025Z 
2020-02-29T10:50:44.9994666Z     Unhandled exception: Failed to parse '1' with format 'YYYY'. 1-02-29 is not a valid date [TimeParseError]

Expected Output

should pass

Additional Information

  • by the time I fixed fix #13543 (CI will break every 4 years on feb 29) and add times.isLeapDay #13547 the local time was already past feb29 and the 2nd failure didn't manifest, so I wasn't aware of it until i saw some old logs in other PRs
  • this time it's a bug i stdlib, not in the test.
  • toDateTime relies on now which, when now is feb 29, causes bugs
  • newly introduced isLeapDay will probably be useful in a fix for this

minimal example

  • either wait 4 y or simply edit getTime to return a time that falls on a feb 29, eg right now
    result = initTime(a.tv_sec.int64 - (3600*24*2), convert(Microseconds, Nanoseconds, a.tv_usec.int))
    (or compute tv_sec directly)
    the run:
import times
echo parse("1", "YYYY", utc()).year # will crash

=> will crash with same error

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions