计算夏令时和非夏令时的时差

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

我想计算夏令时和非夏令时的时差。但是我不知道怎么让R知道一个时间是不是夏令时。

比如凤凰城夏天不调整夏令时,而美国大部分地区都会调整。如果我想计算下面的时差,应该是 3 小时而不是 2 小时。 tzone = "America/Phoenix"会自动设置时间为"MST",这是夏令时,但这不是我想要的

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.

我尝试通过设置 tzone="EDT" 或 "MDT" 来解决这个问题。但似乎 R 不允许识别这些时区。

> 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'

MST 和 EST 中的 "S" 代表 "standard." 这始终是非夏令时版本。您想在东部夏令时使用 EDT。

这是一种方法。我使用 anytime() 方便(来自 anytime 包)

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> 

您必须通过显式文本表示(这是浪费),因为底层表示始终采用 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> 

期望的/怀疑的时差仅在夏季出现。使用 7 月而不是 12 月:

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> 

当然,这里使用 anytime() 完成的所有操作都可以使用 Base R 函数完成。这只是一个捷径,一切都取决于POSIXt如何处理。

编辑:我忘了我在另一个包里还有另一个帮手:

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

您遇到问题是因为 EST。来自 ?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...

使用 US/EasternAmerica/New_York 而不是 EST。有关详细信息,请参阅 ?OlsonNames()

#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