user1700890
user1700890

Reputation: 7742

as.POSIXct, timezone part is ignored

Here is my example.

test <- as.POSIXct(as.Date("2019-11-01"), tz = "UTC")
test

It prints:

[1] "2019-10-31 19:00:00 CDT"

It looks like it ignored tz parameter:

attr(test, "tzone")

returns NULL.

Why is it coming with "19" hours and not 00? How can I make it 00 hours and take UTC?

UPDATE Here is even better case:

test_2 <- as.POSIXct("2019-11-01 00:00:00", tz = "UTC")
str(test_2)
attr(test_2, "tzone")
strftime(test_2, "%H")

It generates:

POSIXct[1:1], format: "2019-11-01"
[1] "UTC"
[1] "19"

Now it looks like parameter tz is not ignored, but hour is 19, but why?

Upvotes: 1

Views: 144

Answers (1)

akrun
akrun

Reputation: 887891

We can use with_tz from lubridate

library(lubridate)
test1 <- with_tz(as.Date("2019-11-01"), tzone = 'UTC')
attr(test1, 'tzone')
#[1] "UTC"

Also, as.POSIXct can be directly applied

test2 <- as.POSIXct("2019-11-01", tz = "UTC")
test2
#[1] "2019-11-01 UTC"
attr(test2, 'tzone')
#[1] "UTC"

With strftime, use the option for tz

strftime(test2, "%H", tz = 'UTC')
#[1] "00"

If we check the strftime, it is doing a second conversion with as.POSIXlt and then with format gets the formatted output

strftime
function (x, format = "", tz = "", usetz = FALSE, ...) 
format(as.POSIXlt(x, tz = tz), format = format, usetz = usetz, 
    ...)

According to ?as.POSIXlt

tz - time zone specification to be used for the conversion, if one is required. System-specific (see time zones), but "" is the current time zone, and "GMT" is UTC (Universal Time, Coordinated). Invalid values are most commonly treated as UTC, on some platforms with a warning.

as.POSIXlt(test2)$hour
#[1] 0
as.POSIXlt(test2, tz = "")$hour
#[1] 20

The "" uses the Sys.timezone by default

as.POSIXlt(test2, tz = Sys.timezone())$hour
#[1] 20

Upvotes: 1

Related Questions