Bin
Bin

Reputation: 547

Calculate time differences between daylight saving time and non-daylight saving time

I want to calculate time differences between daylight saving time and non-daylight saving time. But I do not know how to let R know that a time is daylight saving time or not.

For example, Phoenix do not adjust daylight saving time in the summer, whereas most areas in US do. If I wanna calculate the time differences in the following, it's supposed to be 3 hours rather than 2 hours. tzone = "America/Phoenix" will automatically set the time as "MST", which is a daylight saving time, but this is not what I want.

library(lubridate)
x <- "22/5/2016 23:50"
x <- dmy_hm(x)
x1 <- force_tz(x, tzone = "America/Phoenix")
x2 <- force_tz(x, tzone = "EST")

x1-x2
# The output is "Time difference of 2 hours". But actually it is supposed to be 3 hours.

I tried by setting tzone="EDT" or "MDT" to fix that. But it seems that R do not allow recognize those timezones.

> x2 <- force_tz(y, tzone = "EDT")
Warning messages:
1: In as.POSIXct.POSIXlt(lt) : unknown timezone 'EDT'
2: In as.POSIXlt.POSIXct(ct) : unknown timezone 'EDT'
> x3 <- force_tz(y, tzone = "MDT")
Warning messages:
1: In as.POSIXlt.POSIXct(x, tz) : unknown timezone 'EDT'
2: In as.POSIXct.POSIXlt(lt) : unknown timezone 'MDT'
3: In as.POSIXlt.POSIXct(ct) : unknown timezone 'MDT'

Upvotes: 1

Views: 1019

Answers (3)

d.b
d.b

Reputation: 32548

You have a problem because of EST. From ?timezone:

Beware that some of these designations may not be what you expect: in particular EST is a time zone used in Canada without daylight saving time...

Use US/Eastern or America/New_York instead of EST. See ?OlsonNames() for more information.

#DST
x1 = as.POSIXct("22/5/2016 23:50", format = "%d/%m/%Y %H:%M", tz = "America/New_York")
x2 = as.POSIXct("22/5/2016 23:50", format = "%d/%m/%Y %H:%M", tz = "America/Phoenix")
x2 - x1
#Time difference of 3 hours

#NOT DST
x1 = as.POSIXct("22/12/2016 23:50", format = "%d/%m/%Y %H:%M", tz = "America/New_York")
x2 = as.POSIXct("22/12/2016 23:50", format = "%d/%m/%Y %H:%M", tz = "America/Phoenix")
x2 - x1
#Time difference of 2 hours

Upvotes: 3

Dirk is no longer here
Dirk is no longer here

Reputation: 368261

Here is one way. I use anytime() for convenience (from the anytime package)

R> nyc <- format(anytime("12/05/2016 23:50", tz="America/New_York"))
R> phx <- format(anytime("12/05/2016 23:50", tz="America/Phoenix"))
R> diff(anytime(c(phx, nyc)))
Time difference of 2 hours
R> 

You have to go through explicit textual representation (which is wasteful) as the underlying representation is always in UTC:

R> difftime(anytime("12/05/2016 23:50", tz="America/New_York"),
+           anytime("12/05/2016 23:50", tz="America/Phoenix"))
Time difference of 0 secs
R> 

The desired / suspected three hour difference occurs only in the summer. Using July instead of December:

R> phx <- format(anytime("07/05/2016 23:50", tz="America/Phoenix"))
R> nyc <- format(anytime("07/05/2016 23:50", tz="America/New_York"))
R> diff(anytime(c(phx, nyc)))
Time difference of 3 hours
R> 

And of course, all that is done here with anytime() can be done with Base R functions. This is just a shortcut, and it all comes down to how POSIXt handles this.

Edit: I forgot that I have another helper in another package:

R> RcppCCTZ::tzDiff("America/Phoenix", "America/New_York", anytime("2016-05-22"))
[1] 3
R> 

Upvotes: 2

Michael Stroud
Michael Stroud

Reputation: 279

The "S" in MST and EST stands for "standard." That's always the non-daylight savings version. You want to use EDT for eastern daylight time.

Upvotes: 0

Related Questions