Reputation: 303
I know similar things have been discussed but here's a few things I haven't found answers yet.
> Sys.timezone()
[1] "EST"
> as.POSIXct("2011-01-30")
[1] "2011-01-30 EST"
> as.POSIXct(as.Date("2011-01-30"))
[1] "2011-01-29 19:00:00 EST"
> as.POSIXct(as.Date("2011-01-30"), tz="EST")
[1] "2011-01-29 19:00:00 EST"
> as.POSIXct(as.Date("2011-01-30"), tz="GMT")
[1] "2011-01-29 19:00:00 EST"
> as.POSIXct(as.Date("2011-01-30"), tz="America/New_York")
[1] "2011-01-29 19:00:00 EST"
> as.POSIXct(as.Date("2011-01-30"), tz="")
[1] "2011-01-29 19:00:00 EST"
Can anybody tell me why, if the input is a Date, I cannot get midnight January 30 even though I specified the correct time zone? While if the input is character string then I'm OK.
Both are horribly slow. Then I found that to convert a character string to a Date it's actually a lot faster by converting it to POSIXlt first:
> d3.str = "2011-03-02 23:59:00";
> N=10000
> system.time(for(i in 1:N) r5.dt = as.Date(d3.str))
user system elapsed
1.25 0.00 1.24
> system.time(for(i in 1:N) r6.dt = as.Date(strptime(d3.str, format="%Y-%m-%d")))
user system elapsed
0.37 0.00 0.38
> r5.dt
[1] "2011-03-02"
> r5.dt==r6.dt
[1] TRUE
I'm now confused. Is there any faster, more elegant way to convert a character to a Date? And a Date to a character instead as.character which is also quite slow?
Thank you in advance!
Upvotes: 3
Views: 12369
Reputation: 263301
Very early in the as.POSIXct help page we read: "Dates without times are treated as being at midnight UTC." Your expectation that the 'tz' argument will modify this is simply mistaken. You can get the original date if you specify the output to be in UCT:
strftime(as.POSIXct(as.Date("2011-01-30")), format="%Y-%m-%d %H:%M:%S", tz="UCT")
#[1] "2011-01-30 00:00:00"
If you really just want a date then you should use as.Date
.
Upvotes: 7
Reputation: 173517
As for your second question, a lot will probably be clearer if you compare the code for as.Date.character
and as.Date.POSIXlt
. One of them has to do a lot more checking of stuff since you haven't specified a format.
As for general speed, you aren't vectorizing your conversions. as.Date
and strptime
and most other Date/Time conversion functions accept vectors of dates and DateTimes. It will be considerably faster than way.
Upvotes: 4
Reputation: 32351
The tz
argument of as.POSIXct is only used with strings, and (silently) ignored otherwise. You may want to look at packages designed to help manipulate dates, e.g., the with_tz
function in the lubridate
package.
Upvotes: 2