Skip to content

as.ITime should round sub-second values instead of floor/truncate #2870

@rossholmberg

Description

@rossholmberg

(referencing closed issue #2156 as requested by Matt)

as.ITime converts time strings to integers, so it makes sense that any inputs with sub-second precision would be rounded to the nearest second. Unfortunately, it always rounds down (probably just truncating the input to discard decimal values), which doesn't seem like the best option to me.

The issue

For example:

> as.ITime( "00:00:10.999" )
[1] "00:00:10"

This isn't just being printed that way, the integer behind the scenes agrees with the printed value:

> as.numeric( as.ITime( "00:00:10.999" ) )
[1] 10

Comparison with chron::times

The chron package uses numeric instead of integer values, so this isn't an issue there:

> chron::times( "00:00:10.999" )
[1] 00:00:11

# multiply here to convert to number of seconds since midnight for comparison
> as.numeric( chron::times( "00:00:10.999" ) ) * 24*60*60
[1] 10.999

Comparison with as.POSIXct

as.POSIXct prints the "truncated" value, but retains the sub-second precision in the numeric value behind the scenes:

> as.POSIXct( "1970-01-01 00:00:10.999", tz = "UTC" )
[1] "1970-01-01 00:00:10 UTC"
> as.numeric( as.POSIXct( "1970-01-01 00:00:10.999", tz = "UTC" ) )
[1] 10.999

Something odd I noticed with as.POSIXct

Oddly, POSIXct seems to truncate sometimes, possibly depending on timezone, and possibly something to do with negative numbers. Not sure why this is, and it's not related to data.table at all, just something I noticed when looking at the above, so you might notice it too:

> as.POSIXct( "1970-01-01 00:00:10.999", tz = "UTC" )
[1] "1970-01-01 00:00:10 UTC"
> as.POSIXct( "1970-01-01 00:00:10.999", tz = "Australia/Melbourne" )
[1] "1970-01-01 00:00:11 AEST"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions