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

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

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

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

> 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 и timezones. Мой /etc/localtime установлен в Европу/Амстердам. Я не мог найти способ установить tz в UTC, кроме установки переменной окружения TZ:

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

Возможно ли установить часовой пояс при создании POSIXct из yearmon или Date?

Изменить:

Я проверил функции as.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. Пока я буду использовать предложение Ричи, чтобы установить tzone вручную, используя:

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

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

Ответ 1

Это связано с тем, что as.POSIXct.Date не передает ... в .POSIXct.

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

Ответ 2

Вы правильно настроили часовой пояс в своем коде. Проблема, которую вы воспринимаете, только на выходном этапе. Все значения POSIX имеют отношение к UTC/GMT. Сроки считаются полуночи. Полуночный UTC - 1 AM CET (который, очевидно, где вы находитесь).

> as.POSIXct(as.yearmon("2010-01-01"), tz="UTC")
[1] "2009-12-31 19:00:00 EST"     # R reports the time in my locale 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 для многих и многих других форматов.

Ответ 3

Это кажется странным с методами класса даты и времени "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"

Ответ 4

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

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

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


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

Даты без времени рассматриваются как находясь в полночь UTC.

Итак, в вашем примере аргумент 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"))