as.POSIXct дает неожиданный часовой пояс

Я пытаюсь преобразовать дату yearmon (из пакета zoo) в POSIXct в часовом поясе UTC. Вот что я пытался сделать:

> as.POSIXct(as.yearmon("2010-01-01"), tz="UTC")
[1] "2010-01-01 01:00:00 CET"

Я получаю то же самое, когда конвертирую дату:

> as.POSIXct(as.Date("2010-01-01"),tz="UTC")
[1] "2010-01-01 01:00:00 CET"

Единственный способ заставить его работать - передать символ в качестве аргумента:

> as.POSIXct("2010-01-01", tz="UTC")
[1] "2010-01-01 UTC"

Я посмотрел на документацию по DateTimeClasses, tzset и часовым поясам. Мой /etc/localtime настроен на Европу / Амстердам. Я не смог найти способ установить tz в UTC, кроме как установить переменную окружения TZ:

> Sys.setenv(TZ="UTC")
> as.POSIXct(as.Date("2010-01-01"),tz="UTC")
[1] "2010-01-01 UTC"

Можно ли напрямую установить часовой пояс при создании POSIXct из года или даты?

Редактировать:

Я проверил функции как.POSIXct.yearmon. Этот переходит к as.POSIXct.Date.

> zoo:::as.POSIXct.yearmon
function (x, tz = "", ...) 
as.POSIXct(as.Date(x), tz = tz, ...)
<environment: namespace:zoo>

Так, как говорит Джошуа, часовой пояс теряется в as.POSIXct.Date. Сейчас я воспользуюсь предложением Richies, чтобы установить tzone вручную, используя:

attr (x, "tzone") <- 'UTC'

Это решает проблему потерянной зоны, которая используется только для презентации, а не внутри, как предложили Гротендик и Двин.

4 ответа

Решение

Это потому что as.POSIXct.Date не проходит ... в .POSIXct,

> as.POSIXct.Date
function (x, ...) 
.POSIXct(unclass(x) * 86400)
<environment: namespace:base>

Вы правильно устанавливаете часовой пояс в своем коде. Проблема, которую вы воспринимаете, только на стадии вывода. Все значения POSIX относятся к UTC/GMT. Даты предполагаются в полночь. Полночь по Гринвичу - 1:00 по центральноевропейскому времени.

> as.POSIXct(as.yearmon("2010-01-01"), tz="UTC")
[1] "2009-12-31 19:00:00 EST"     # R reports the time in my locale's timezone
> dtval <- as.POSIXct(as.yearmon("2010-01-01"), tz="UTC")
> format(dtval, tz="UTC")         # report the date in UTC  note it is the correct date ... there
[1] "2010-01-01"
> format(dtval, tz="UTC", format="%Y-%m-%d ")
[1] "2010-01-01 "                 # use a format string
> format(dtval, tz="UTC", format="%Y-%m-%d %OS3")
[1] "2010-01-01 00.000"           # use decimal time

Увидеть ?strptime для многих, многих других возможностей формата.

Это кажется странностью с датой / временем "POSIXct" методы класса. Попробуйте отформатировать "Date" или же "yearmon" сначала переменная, так что as.POSIXct.character скорее, чем as.POSIXct.{Date, yearmon} отправляется:

Дата

> d <- as.Date("2010-01-01")
> as.POSIXct(format(d), tz = "UTC")
[1] "2010-01-01 UTC"

yearmon

> library(zoo)
> y <- as.yearmon("2010-01")
> as.POSIXct(format(y, format = "%Y-%m-01"), tz = "UTC")
[1] "2010-01-01 UTC"
> # or
> as.POSIXct(format(as.Date(y)), tz = "UTC")
[1] "2010-01-01 UTC"

На странице справки ?as.POSIXct, для tz аргумент это говорит

Спецификация часового пояса, которая будет использоваться для преобразования, если таковое требуется. Зависит от системы (см. Часовые пояса), но "" "- это текущий часовой пояс, а"GMT"- это UTC (Всемирное время, скоординированное).

Есть ли as.POSIXct(as.yearmon("2010-01-01"), tz="GMT") работа для тебя?


После более подробного изучения документации, в разделе подробностей мы видим:

Даты без учета времени считаются в полночь по Гринвичу.

Так что в вашем примере tz аргумент игнорируется. Если вы используете as.POSIXlt легче увидеть, что происходит с часовым поясом. Следующее должно дать тот же ответ с UTC в качестве часового пояса.

unclass(as.POSIXlt(as.yearmon("2010-01-01")))
unclass(as.POSIXlt(as.yearmon("2010-01-01"), tz = "UTC"))
unclass(as.POSIXlt(as.yearmon("2010-01-01"), tz = "GMT"))
unclass(as.POSIXlt(as.yearmon("2010-01-01"), tz = "CET"))

На самом деле, так как вы используете as.yearmon (что сокращает время ожидания), вы никогда не сможете установить часовой пояс. Сравните, например,

unclass(as.POSIXlt(as.yearmon("2010-01-01 12:00:00"), tz = "CET"))
unclass(as.POSIXlt("2010-01-01 12:00:00", tz = "CET"))
Другие вопросы по тегам