Sebastian P. Luque
2006-Oct-27 16:59 UTC
[R] POSIXct time zone and daylight savings issues
Hello, Suppose we need a function that takes a POSIXct object and need to calculate the time difference between it and GMT time: gmtDiff <- function(time) { time.gmt <- as.POSIXct(format(time, tz="GMT")) time.plt <- as.POSIXlt(time) dlstime <- ifelse(time.plt$isdst > 0, 1, 0) timezone <- as.numeric(difftime(time, time.gmt, units="hours")) timezone - dlstime } Please note this assumes no daylight savings if the 'isdst' component for the POSIXlt object is negative (i.e. don't know if DST is in effect). Now if we pass some values to this function: R> gmtDiff(as.POSIXct("2006-10-27", tz="GMT")) [1] -5 R> gmtDiff(as.POSIXct(Sys.time())) [1] -6 I would have expected the first call to return zero, but it seems as if the calculation is always done with respect to the system's locale, and I can't understand what the function of the 'tzone' attribute is in these calculations. ?strptime has information on how to change the locale for some operations, which in this case didn't change the outcome: R> lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C") [1] "C" R> gmtDiff(as.POSIXct("2006-10-27", tz="GMT")) [1] -5 R> gmtDiff(as.POSIXct(Sys.time())) [1] -6 R> Sys.setlocale("LC_TIME", lct) [1] "en_CA.UTF-8" R> sessionInfo() R version 2.4.0 (2006-10-03) x86_64-pc-linux-gnu locale: LC_CTYPE=en_CA.UTF-8;LC_NUMERIC=C;LC_TIME=en_CA.UTF-8;LC_COLLATE=en_CA.UTF-8;LC_MONETARY=en_CA.UTF-8;LC_MESSAGES=en_CA.UTF-8;LC_PAPER=en_CA.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_CA.UTF-8;LC_IDENTIFICATION=C attached base packages: [1] "methods" "stats" "graphics" "grDevices" "utils" "datasets" [7] "base" other attached packages: lattice "0.14-9" I'd be grateful for any clarification and advice on how to properly calculate this time difference. Cheers, -- Seb
Gabor Grothendieck
2006-Oct-27 18:55 UTC
[R] POSIXct time zone and daylight savings issues
Try this: gmtDiff <- function(time) time - as.POSIXct(format(time), tz = "GMT") gmtDiff(Sys.time()) gmtDiff(as.POSIXct("2006-10-27", tz = "GMT")) which both give me the correct answer currently. The expression after the minus sign comes from the table at the end of the help desk article in R News 4/1. I think you got the parentheses wrong in your version and I think the isdst calculation needs to be omitted -- I get the right answer if I leave it out but wrong with it. On 10/27/06, Sebastian P. Luque <spluque at gmail.com> wrote:> Hello, > > Suppose we need a function that takes a POSIXct object and need to > calculate the time difference between it and GMT time: > > > gmtDiff <- function(time) { > time.gmt <- as.POSIXct(format(time, tz="GMT")) > time.plt <- as.POSIXlt(time) > dlstime <- ifelse(time.plt$isdst > 0, 1, 0) > timezone <- as.numeric(difftime(time, time.gmt, units="hours")) > timezone - dlstime > } > > > Please note this assumes no daylight savings if the 'isdst' component for > the POSIXlt object is negative (i.e. don't know if DST is in effect). Now > if we pass some values to this function: > > > R> gmtDiff(as.POSIXct("2006-10-27", tz="GMT")) > [1] -5 > R> gmtDiff(as.POSIXct(Sys.time())) > [1] -6 > > > I would have expected the first call to return zero, but it seems as if > the calculation is always done with respect to the system's locale, and I > can't understand what the function of the 'tzone' attribute is in these > calculations. ?strptime has information on how to change the locale for > some operations, which in this case didn't change the outcome: > > > R> lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C") > [1] "C" > R> gmtDiff(as.POSIXct("2006-10-27", tz="GMT")) > [1] -5 > R> gmtDiff(as.POSIXct(Sys.time())) > [1] -6 > R> Sys.setlocale("LC_TIME", lct) > [1] "en_CA.UTF-8" > R> sessionInfo() > R version 2.4.0 (2006-10-03) > x86_64-pc-linux-gnu > > locale: > LC_CTYPE=en_CA.UTF-8;LC_NUMERIC=C;LC_TIME=en_CA.UTF-8;LC_COLLATE=en_CA.UTF-8;LC_MONETARY=en_CA.UTF-8;LC_MESSAGES=en_CA.UTF-8;LC_PAPER=en_CA.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_CA.UTF-8;LC_IDENTIFICATION=C > > attached base packages: > [1] "methods" "stats" "graphics" "grDevices" "utils" "datasets" > [7] "base" > > other attached packages: > lattice > "0.14-9" > > > I'd be grateful for any clarification and advice on how to properly > calculate this time difference. > > > Cheers, > > -- > Seb > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
Sebastian P. Luque
2006-Oct-28 01:19 UTC
[R] POSIXct time zone and daylight savings issues
On Fri, 27 Oct 2006 14:55:15 -0400, "Gabor Grothendieck" <ggrothendieck at gmail.com> wrote:> Try this: gmtDiff <- function(time) time - as.POSIXct(format(time), tz > "GMT")> gmtDiff(Sys.time()) gmtDiff(as.POSIXct("2006-10-27", tz = "GMT"))> which both give me the correct answer currently.> The expression after the minus sign comes from the table at the end of > the help desk article in R News 4/1. I think you got the parentheses > wrong in your version and I think the isdst calculation needs to be > omitted -- I get the right answer if I leave it out but wrong with it.Thanks Gabor, this provides the correct result, and the isdst calculation is no longer needed. Cheers, -- Seb