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

IDateTime fails on POSIXct without tzone. #1973

Closed
lbilli opened this issue Dec 25, 2016 · 2 comments
Closed

IDateTime fails on POSIXct without tzone. #1973

lbilli opened this issue Dec 25, 2016 · 2 comments
Milestone

Comments

@lbilli
Copy link

lbilli commented Dec 25, 2016

The function IDateTime generates an error when applied to POSIXct values without tzone attribute:

library(data.table)
IDateTime(Sys.time())
# Error in if (tz == "UTC") { : argument is of length zero

Versions
R: 3.3.2
data.table: 1.10.0 and latest 1.10.1

@lbilli
Copy link
Author

lbilli commented Mar 14, 2017

Some more insights.

library(data.table)
x <- Sys.time()

attr(x, "tzone")
# NULL

IDateTime(x)
# Error in if (tz == "UTC") { : argument is of length zero

However, curiously this works as expected:

data.table(idate = as.IDate(x), itime = as.ITime(x))
#         idate    itime
# 1: 2017-03-14 09:27:09

There's no issue if x has a tzone attribute (even if it's an empty string):

x <- as.POSIXct("2017-03-14 09:16:14")

attr(x, "tzone")
# [1] ""

IDateTime(x)
#         idate    itime
# 1: 2017-03-14 09:16:14

This issue is still present with these versions:
R: 3.3.3
data.table: 1.10.4

@MichaelChirico
Copy link
Member

MichaelChirico commented Mar 17, 2017

This almost feels like an R bug more than a data.table bug.

It seems like by default a POSIXct object is supposed to have non-NULL "tzone" attribute:

attr(as.POSIXct('2017-03-17 00:00:00'), 'tzone')
#[1] ""

But this isn't the case for Sys.time():

attr(Sys.time(), 'tzone')
# NULL

And in fact strptime suggests a NULL tz value is illegal:

as.POSIXct('2017-03-17 00:00:00', tz = NULL)

Error in strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz) :
invalid tz value

There's something going on with lazy evaluation that's causing the discrepancy between

IDateTime(Sys.time())

Error in if (tz == "UTC") { : argument is of length zero

and

x = Sys.time()
data.table(idate = as.IDate(x), itime = as.ITime(x))
#         idate    itime
# 1: 2017-03-17 16:28:10

(this is an unexpected error because IDateTime.default is precisely the above):

data.table:::IDateTime.default
# function (x, ...) 
# {
#     data.table(idate = as.IDate(x), itime = as.ITime(x))
# }

Due to lazy evaluation, x is unevaluated when it gets passed to as.IDate, and hence gets sent to as.IDate.default, whereas for IDateTime(Sys.time()), Sys.time() has been evaluated before being passed to as.IDate, so it gets sent to as.IDate.POSIXct. as.Date(x, ...) excludes the tz argument, so it picks up the default of "UTC".

@mattdowle mattdowle added this to the v1.10.6 milestone May 11, 2017
mattdowle added a commit that referenced this issue May 11, 2017
Closes #1973; lazyeval edge case of IDateTime caused an error in as.D…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants