2017-02-21 148 views
1

我想计算夏令时和非夏令时之间的时差。但我不知道如何让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' 
+0

* *夏天* *不是冬天* * 3 *小时。看到我的答案。 –

+0

谢谢,德克!你的代码有效。但我的代码中的意思是夏天。我把月份放在月份前面。为了澄清它,我将原始日期修改为22/5/2016 – Bin

+0

啊。这是一种常见的日期格式,但很容易出错(至少在世界的这一部分)。最好坚持2016-05-22。 –

回答

3

你有因为EST问题。从?timezone

要小心,有些名称可能不是你所期望的:在 特别EST在加拿大没有使用夏令时 一个时区...

使用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 
+2

正确的答案和良好的基础R解决方案。 Upvoting ... –

0

MST和EST中的“S”代表“标准”。这总是非夏令时版本。你想在东部夏令时使用EDT。

+0

但R不识别“EDT”等时区。也许是“EST5EDT” – Bin

+1

。 “东部时间”因澳大利亚人拥有自己的“东部”地带而出名。(和“美国人”在他们的假设中是有名的。) –

2

这是一种方法。我用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> 

所需/怀疑三个小时的差异只发生在夏季。使用七月代替十二月:

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()做可以与基础R函数来完成。这只是一条捷径,而这一切都归结于POSIXt如何处理这一点。

编辑:我忘了,我在另一个包装的另一个帮手:

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