Skip to content

Document leap second handling (in FAQ article)? #309

Description

@trevorld

Perhaps it would make sense to document how {clock} handles leap seconds? Perhaps in the FAQ article?

I'm observing that on my computer {clock} parses leap seconds as NA values (and issues a Warning) and that differences between UTC times are in POSIX seconds (instead of SI/metric seconds)

Package Parsing leap seconds Difference between UTC times
{clock} as NA POSIX seconds
{nanotime} as next second POSIX seconds
base::as.POSIXct() as next second POSIX seconds
base::as.POSIXlt() as leap second POSIX seconds (probably after conversion to POSIXct())
# `base::.leap.seconds` contains (the second after) all UTC leap seconds (so far)
# Due to leap second at end of 2005 here are three different UTC seconds
leap_before <- "2005-12-31T23:59:59"
leap_second <- "2005-12-31T23:59:60"
leap_after <- "2006-01-01T00:00:00"

## (on my computer) {clock} won't parse, differences are POSIX seconds
library("clock")
year_month_day_parse(leap_second, precision = "second")
Warning: Failed to parse 1 string at location 1. Returning `NA` at that location.
<year_month_day<second>[1]>
[1] NA
naive_time_parse(leap_second)
Warning: Failed to parse 1 string at location 1. Returning `NA` at that location.
<clock_naive_time[1]>
[1] NA
sys_time_parse(leap_second)
Warning: Failed to parse 1 string at location 1. Returning `NA` at that location.
<clock_sys_time[1]>
[1] NA
# Difference of two metric seconds but (on some computers) one POSIX second
sys_time_parse(leap_after) - sys_time_parse(leap_before)
<duration<second>[1]>
[1] 1
## {nanotime} will parse as next second, differences are POSIX seconds
library("nanotime")
as.nanotime(paste0(leap_second, "Z"))
[1] 2006-01-01T00:00:00+00:00
as.nanotime(paste0(leap_after, "Z")) - as.nanotime(paste0(leap_before, "Z"))
[1] 00:00:01
## as.POSIXct() will parse as next second, differences are POSIX seconds
as.POSIXct(leap_second, format = "%FT%T", tz = "UTC") |> format(format = "%F %T")
[1] "2006-01-01 00:00:00"
as.POSIXct(leap_after, format = "%FT%T", tz = "UTC") - as.POSIXct(leap_before, format = "%FT%T", tz = "UTC")
Time difference of 1 secs
## as.POSIXlt() will correctly parse leap second...
## but differences are POSIX seconds (presumably converted to `POSIXct` before differencing)
as.POSIXlt(leap_second, format = "%FT%T", tz = "UTC") |> format(format = "%F %T")
[1] "2005-12-31 23:59:60"
as.POSIXlt(leap_after, format = "%FT%T", tz = "UTC") - as.POSIXlt(leap_before, format = "%FT%T", tz = "UTC")
Time difference of 1 secs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions