Как извлечь правильные часовые пояса из объектов POSIXct и POSIXlt?
time1 = as.POSIXlt("2010-07-01 16:00:00", tz="Europe/London")
time1
# [1] "2010-07-01 16:00:00 Europe/London"
но
time2 = as.POSIXct("2010-07-01 16:00:00", tz="Europe/London")
time2
# [1] "2010-07-01 16:00:00 BST"
Почему часовой пояс представлен по-разному? Это важно для меня, потому что мне нужно извлечь часовые пояса с моей даты.
base::format(time1, format="%Z")
# [1] "BST"
base::format(time2, format="%Z")
# [1] "BST"
оба дают один и тот же "BST" для британского Экономического времени!
Проблема заключается в том, что "BST" не является швом для распознавания в формате POSIXct/POSIXlt:
as.POSIXlt("2010-07-01 16:00:00", tz="BST")
# [1] "2010-07-01 16:00:00 BST"
# Warning messages:
# 1: In strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz) :
# unknown timezone 'BST'
# 2: In structure(xx, class = c("POSIXct", "POSIXt"), tzone = tz) :
# unknown timezone 'BST'
# 3: In strptime(x, f, tz = tz) : unknown timezone 'BST'
as.POSIXct("2010-07-01 16:00:00", tz="BST")
# [1] "2010-07-01 16:00:00 GMT"
# Warning messages:
# 1: In strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz) :
# unknown timezone 'BST'
# 2: In structure(xx, class = c("POSIXct", "POSIXt"), tzone = tz) :
# unknown timezone 'BST'
# 3: In strptime(x, f, tz = tz) : unknown timezone 'BST'
# 4: In structure(xx, class = c("POSIXct", "POSIXt"), tzone = tz) :
# unknown timezone 'BST'
# 5: In as.POSIXlt.POSIXct(x, tz) : unknown timezone 'BST'
Я действительно смущен.
У меня есть 2 вопроса:
1/В чем разница между форматами POSIXct и POSIXlt
2/Кто-нибудь знает, какой часовой пояс я могу использовать?
"Европа/Лондон" работает с POSIXlt, но не POSIXct. Кроме того, он не может быть извлечен из времени, используя base:: format
"BST" не признается действительным часовым поясом в функциях as.POSIXct
или as.POSIXlt
.
Ответы
Ответ 1
@Koshke показал вам уже
- разница во внутреннем представлении обоих типов дат и
- что внутренние спецификации обоих часовых поясов одинаковы.
Вы можете получить часовой пояс в стандартном порядке, используя attr()
. Это вызовет часовой пояс в форме, указанной в файле zone.tab
, который используется R для определения часовых поясов (дополнительная информация в ?timezones
).
например:
> attr(time1,"tzone")
[1] "Europe/London"
> attr(time2,"tzone")
[1] "Europe/London"
Я очень удивлен тем, что POSIXct использует разные указания для часовых поясов, чем POSIXlt, тогда как атрибуты равны. По-видимому, этот "BST" появляется только при печати POSIXct. Прежде чем распечатать, POSIXct снова преобразуется в POSIXlt, а атрибут tzone изменяется с синонимами:
> attr(as.POSIXlt(time2),"tzone")
[1] "Europe/london" "GMT" "BST"
Это происходит где-то ниже внутренней функции R as.POSIXlt
, на которую я пока не могу смотреть из-за более острых проблем. Но не стесняйтесь пройти через это и посмотреть, что именно происходит там.
В боковом поле "BST" не распознается как часовой пояс (и он не упоминается в zone.tab) в моей установке Windows 7/R 2.13.0.
Ответ 2
возможно, unclass
объекты помогут вам проверить различия:
> unclass(time1)
$sec
[1] 0
$min
[1] 0
... snip
$yday
[1] 181
$isdst
[1] 1
attr(,"tzone")
[1] "Europe/London"
> unclass(time2)
[1] 1277996400
attr(,"tzone")
[1] "Europe/London"
Таким образом, POSIXlt содержит дату как список компонентов, в то время как POSIXct содержит его как числовое, то есть время в UNIX-времени.
Что касается часового пояса, это выходит за рамки Р.
См. Объяснение в http://en.wikipedia.org/wiki/Tz_database
Что касается разного поведения
as.POSIXct("2010-07-01 16:00:00", tz="BST")
as.POSIXlt("2010-07-01 16:00:00", tz="BST")
Я подозреваю, что есть ошибка в as.POSIXct, которая не обрабатывает аргумент tz.
Ответ 3
1/В чем разница между форматами POSIXct и POSIXlt
-
POSIXct
- секунды с эпоха
-
POSIXlt
разделяет datetimes на %Y-%m-%d
или %Y/%m/%d %H:%M:%S
или другие такие форматы