2017-01-30 15 views
1

Я подозреваю, что делаю что-то очень глупо, но я не могу получить dst функцию в lubridate для работы, как ожидалось.R: lstrite dst() работает не так, как ожидалось

library(lubridate) 

x <- c("2016-01-01", "2016-06-01") 

dst(x) # Returns c(FALSE, TRUE) 
dst(as.Date(x)) # Returns c(FALSE, FALSE) 

В результате я ожидаю, в обоих случаях c(FALSE, TRUE). Однако я получаю только ожидаемый результат, если передаю dst символьный вектор, а не объект Date. Я использую OS X, мой текущий часовой пояс PST (America/Los_Angeles).

+2

hi pbaylis, можете ли вы рассказать нам, какого результата вы ожидаете? –

+1

'dst (x)' возвращает 'c (FALSE, FALSE)' для меня. В какой часовой зоне вы находитесь? 'dst (x)' вызывает 'as.POSIXlt (x) $ isdst', который использует системный часовой пояс. – thelatemail

+0

Я ожидаю 'c (FALSE, TRUE)' и я в PST (отредактированный вопрос соответственно). – pbaylis

ответ

3

dst() называет кусок кода, который является по существу:

c(NA, FALSE, TRUE)[as.POSIXlt(x)$isdst + 2] 

as.POSIXlt является по умолчанию:

as.POSIXlt(x=, tz="") 

... который будет принимать вашу систему часовой пояс по умолчанию. Итак, учитывая ваше местоположение в L.A., давайте посмотрим:

as.POSIXlt(x, tz="America/Los_Angeles") 
#[1] "2016-01-01 PST" "2016-06-01 PDT" 
c(NA, FALSE, TRUE)[as.POSIXlt(x, tz="America/Los_Angeles")$isdst + 2] 
#[1] FALSE TRUE 

Все в порядке. Ура. Теперь, давайте попробуем с as.Date(x)

as.POSIXlt(as.Date(x)) 
#[1] "2016-01-01 UTC" "2016-06-01 UTC" 
as.POSIXlt(as.Date(x), tz="America/Los_Angeles") 
#[1] "2016-01-01 UTC" "2016-06-01 UTC" 

ооо. Таким образом, as.POSIXlt не играет хорошо с объектами Date и всегда возвращает UTC вместо местного часового пояса и, по-видимому, игнорирует любой аргумент tz=. А так как UTC не соблюдает ни одну летнюю экономию, вы всегда будете возвращены FALSE.

Рассматривая исходный код R, похоже, это так. В https://svn.r-project.org/R/trunk/src/main/datetime.c вы можете найти:

# R call: 
#> as.POSIXlt.Date 
#function (x, ...) 
#.Internal(Date2POSIXlt(x)) 

# source code: 
#SEXP attribute_hidden do_D2POSIXlt(SEXP call, SEXP op, SEXP args, SEXP env) 
#{ 
#... 
setAttrib(ans, s_tzone, mkString("UTC")); 

... как жестко запрограммированной строки.

+0

Спасибо, это освещает. Мне это кажется ошибкой, но я не уверен. В [документации] (https://stat.ethz.ch/R-manual/R-devel/library/base/html/as.POSIXlt.html) для 'as.POSIXlt' говорится:« Даты без времени рассматриваются как в полночь UTC ", так что, возможно, это ожидаемое поведение. Моим обходным решением пока является использование 'as.character (as.Date (x))', но у меня есть большой набор данных, и преобразование в вектор символа является дорогостоящим. – pbaylis