2017-02-21 66 views
1

Я хочу рассчитать разницу во времени между летним временем и не летнее время. Но я не знаю, как сообщить R, что время - это летнее время или нет.Рассчитать разницу во времени между летним временем и не летним временем

Например, Phoenix не регулирует летнее время летом, тогда как в большинстве районов США. Если я хочу рассчитать разницу во времени в следующем, это должно быть 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

Это * три * часа в * лето * не зима. См. Мой ответ. –

+0

Спасибо, Дирк! Ваш код работает. Но то, что я имею в виду в моем коде, - летнее время. Я поставил дату перед месяцем. Чтобы уточнить это, я изменяю исходную дату до 22/5/2016 – Bin

+0

Ahh. Это общий формат даты, но легко ошибиться (по крайней мере, в этой части мира). Лучше всего придерживаться 2016-05-22. –

ответ

3

У вас есть проблемы из-за EST. От ?timezone:

Имейте ввиду, что некоторые из этих обозначений не может быть то, что вы ожидаете: в частности EST является часовой пояс используется в Канаде без спасительной время дневного света ...

Использование US/Eastern или America/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

«S» в MST и EST означает «стандарт». Это всегда не дневная летняя версия. Вы хотите использовать EDT для восточного дневного света.

+0

Но R не распознает часовые пояса, такие как «EDT». – Bin

+1

"EST5EDT" возможно. «Восточное время» классно двусмысленно, так как австралиецы имеют свою «восточную» зону.(И «американцы» лихо замкнуты в своих предположениях.) –

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() можно сделать с помощью функции Base R. Это всего лишь ярлык, и все сводится к тому, как это делает POSIXt.

Edit: Я забыл, что у меня есть еще один помощник в другом пакете:

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