2017-01-01
不應該是PDT
,夏令時是錯誤的。這就是爲什麼如果你看看d$dates
,你會發現你的時區顯然是顛倒的:R是「解決問題」(即使你不希望它)。有人可能會嘗試使用format=...
參數到as.POSIXct
,但輸入時不存在%
-代碼,因此沒有幫助。
此外,d$dates
顯示時區的事實是因爲R在分析時間時認真(/不小心?)假定您的本地時區。這可以通過更改日期的一個UTC顯示:
d = data.frame(dates = c(as.POSIXct("2017-01-01 PDT"), as.POSIXct("2017-04-02 UTC")))
d$dates
# [1] "2017-01-01 PST" "2017-04-02 PDT"
# ^^^ is not UTC
此外,R似乎並不明白"PDT"
作爲一個時區:
as.POSIXct("2017-01-01", tz = "PDT")
# ... lots of warnings ...
# [1] "2017-01-01 GMT"
但不接受類似的東西:
as.POSIXct("2017-01-01", tz = "PST8PDT")
# [1] "2017-01-01 PST"
如果你真的想要的是從原始字符串的字面部分,那麼只需d$TZ <- gsub(".* ", "", d$dates)
會給你,但如果你的意圖不是美容/印刷,這些可能並不全都被R識別。你可能需要翻譯成「已知」的東西。
一種方法是將源更改爲使用小時偏移而不是時區(例如,-0800
而不是PDT
)。這樣做,你可以分析它:(我假設,因爲你正在使用as.POSIXct
副想要的日期/時間標記,不只是一個日期as.Date
)
as.POSIXct("2017-01-01 -0500", format = "%Y-%m-%d %z")
# [1] "2016-12-31 21:00:00 PST"
as.POSIXct("2017-01-01 -0500", format = "%Y-%m-%d %z", tz = "UTC")
# [1] "2017-01-01 05:00:00 UTC"
另一種方法是在已知時區列表中翻譯建議的時區。您可以通過?timezones
(另一個相關Q/A here)找到已知時區。
一個小測試之後(請測試這個進一步的),我想出了這個:
converttz <- function(x) {
on <- OlsonNames()
ind <- sapply(gsub(".* ", "", x), function(z) head(grep(z, on), n = 1))
ret <- character(length(x))
ret[lengths(ind) == 0] <- NA
ret[lengths(ind) > 0] <- on[unlist(ind[lengths(ind) > 0])]
ret
}
這工作只要情況下是正確的;也就是說,"est"
可能與"America/Creston"
一樣容易匹配,即使您只在字符串的開頭或結尾進行搜索,它仍然可以匹配"Europe/Budapest"
。
從這裏,像這樣的工作:
dts <- c("2017-01-01 PDT", "2017-04-02 UTC")
d <- data.frame(dates = as.POSIXct(dts), stringsAsFactors = FALSE)
d$TZ <- converttz(dts)
str(d)
# 'data.frame': 2 obs. of 2 variables:
# $ dates: POSIXct, format: "2017-01-01" "2017-04-02"
# $ TZ : chr "PST8PDT" "Etc/UTC"
好了,"Etc/UTC"
不是很悅目。 "UTC"
確實存在,但它是第二個匹配的,因此被head
過濾掉了。您可以嘗試其他方法來找到更接近的匹配(可能先查找完全匹配,然後再查找開始/結束)。