-2

For sanity check, I want to see if a few minutes after the transition time from DST to ST, would give the same hour for the equivalent Eastern time and UTC. In Canada, on the first Sunday of November time changes from 2:00 AM to 1:00 AM. For simplicity, I only look at 1 timezone from 2012 to 2016.

Here is the my code that reproduces the data as well:

require(timeDate)
timezones <- data.frame(TZname=rep(c('America/Vancouver'),each=5))
timezones$TZname <- as.character(timezones$TZname)
timezones$DST_end <- paste(as.character(timeNthNdayInMonth(paste0(as.character(2012:2016), '-11-01'), nday=0, nth=1)), '1:00')

# initialize a column
timezones$ET_DST_end <- .POSIXct(integer(nrow(timezones)))
for (i in 1:nrow(timezones)) {

        timezones$ET_DST_end[i] <- as.POSIXct(timezones$DST_end[i], tz=timezones$TZname[i])
}
timezones$UTC_DST_end <- format(timezones$ET_DST_end, tz='UTC')

dput(timezones)
# Below is the result

structure(list(TZname = c("America/Vancouver", "America/Vancouver", 
"America/Vancouver", "America/Vancouver", "America/Vancouver"
), DST_end = c("2012-11-04 1:00", "2013-11-03 1:00", "2014-11-02 1:00", 
"2015-11-01 1:00", "2016-11-06 1:00"), ET_DST_end = structure(c(1352016000, 
1383465600, 1414915200, 1446364800, 1478419200), class = c("POSIXct", 
"POSIXt")), UTC_DST_end = c("2012-11-04 08:00:00", "2013-11-03 08:00:00", 
"2014-11-02 08:00:00", "2015-11-01 08:00:00", "2016-11-06 08:00:00"
)), .Names = c("TZname", "DST_end", "ET_DST_end", "UTC_DST_end"
), row.names = c(NA, -5L), class = "data.frame")

If I change the value 1:00 to 1:07 in the third line, the last 2 columns of the output will shift forward for one hour in 2012. The output of sessionInfo() is:

R version 3.2.0 (2015-04-16)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.1 (unknown)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] timeDate_3012.100

loaded via a namespace (and not attached):
[1] tools_3.2.0

Q1: Why is this happening?

Q2: Does this mean that timezone conversion is not accurate?

Q3: Shouldn't the UTC hour be 9 instead of 8 since 1:00 AM + 8= 9:00 AM?

Thanks

asiehh
  • 553
  • 12
  • 22
  • 4
    Please use `dput` to provide data. This will maintain the format and the class of each column. –  Jan 15 '16 at 01:43
  • 2
    Timezone issues are difficult. Post `dput(head(timezones, 15))` so that we have a solid basis for correction of your errors (or possibly bug identification, although that is less likely). – IRTFM Jan 15 '16 at 03:18
  • Instead of removing white spaces, could you provide the `dput` of your data? –  Jan 15 '16 at 04:58
  • R's uses OS functionality for handling datetimes and timezones. Please tell us at least your locale, your OS and your R version. Post the output of `sessionInfo()`. – Roland Jan 15 '16 at 08:17
  • Thank you @Roland. I added the sessionInfo output of the data. Hope this helps. – asiehh Jan 15 '16 at 14:34
  • Thank you @Pascal. I added the dput output as well. – asiehh Jan 15 '16 at 14:35
  • Why didn't you simply `dput()`? You were asked by 2 different people. Anyway, I cannot reproduce the problem on Ubuntu using `1:07`. –  Jan 16 '16 at 03:20
  • @Pascal I did add dput results, but Roland could not reproduce them. So I removed it and put the source code instead to guarantee that it is reproducible. – asiehh Jan 18 '16 at 14:55
  • Roland said he cannot reproduce the behavior you see (me neither), not he couldn't use `dput()` output. –  Jan 18 '16 at 22:57
  • @Pascal I put back the dput of the results. I hope it helps. – asiehh Jan 19 '16 at 00:08

1 Answers1

0

I cannot reproduce your results with your code, but maybe this helps anyway. A vector of class POSIXct (the same for POSIXlt) can only have one timezone.

x <- as.POSIXct(c("2015-01-01", "2016-01-01"), tz = "GMT")
str(unclass(x))
# atomic [1:2] 1.42e+09 1.45e+09
# - attr(*, "tzone")= chr "GMT"
as.POSIXct("2015-01-01", tz = "America/Los_Angeles")
#[1] "2015-01-01 PST"
x[1] <- as.POSIXct("2015-01-01", tz = "America/Los_Angeles")
str(unclass(x))
# atomic [1:2] 1.42e+09 1.45e+09
# - attr(*, "tzone")= chr "GMT"

Here is the source code of [<-.POSIXct:

function (x, ..., value) 
{
    if (!length(value)) 
        return(x)
    value <- unclass(as.POSIXct(value))
    cl <- oldClass(x)
    tz <- attr(x, "tzone")
    class(x) <- NULL
    x <- NextMethod(.Generic)
    class(x) <- cl
    attr(x, "tzone") <- tz
    x
}

As you see, the function:

  1. removes the class of the RHS vector,
  2. copies the class and timezone attribute of the LHS vector,
  3. removes the class of the LHS vector,
  4. uses the default [<- method,
  5. restores the stored class and timezone.

Thus, [<- cannot change the timezone of a POSIXct vector.

Roland
  • 127,288
  • 10
  • 191
  • 288