2015-09-02 5 views
1

Есть ли простой способ добавить смещение часового пояса к существующей метке времени (все в UTC)?R добавить смещение часового пояса к классу POSIXct

Для простоты я использую Sys.time() в моем примере, но в реальных данных я делаю DF$ts <- as.POSIXct(..., tz="GMT").

DF <- data.frame("ts" = rep(Sys.time(), 5), 
       "offset"=c("-11:00", "-12:00", "+01:30", "+02:00", "+02:30")) 

# > DF 
#     ts offset 
# 1 2015-09-02 14:35:31 -11:00 
# 2 2015-09-02 14:35:31 -12:00 
# 3 2015-09-02 14:35:31 +01:30 
# 4 2015-09-02 14:35:31 +02:00 
# 5 2015-09-02 14:35:31 +02:30 

Прямо сейчас я выполняю строчные манипуляции, но я не думаю, что это изящно. Например,

offsetSeconds <- function(offset) { 
    time <- as.numeric(strsplit(offset, ":")[[1]]) 
    seconds <- time[1] * 3600 + sign(time[1]) * time[2] * 60 
    return(seconds) 
} 
DF$seconds <- as.numeric(sapply(as.character(DF$offset), offsetSeconds)) 
DF$local_ts <- DF$ts + DF$seconds 

# > DF 
#     ts offset seconds   local_ts 
# 1 2015-09-02 14:35:31 -11:00 -39600 2015-09-02 03:35:31 
# 2 2015-09-02 14:35:31 -12:00 -43200 2015-09-02 02:35:31 
# 3 2015-09-02 14:35:31 +01:30 5400 2015-09-02 16:05:31 
# 4 2015-09-02 14:35:31 +02:00 7200 2015-09-02 16:35:31 
# 5 2015-09-02 14:35:31 +02:30 9000 2015-09-02 17:05:31 

ответ

0
library(lubridate) 
signs <- as.numeric(paste0(substr(DF$offset, 1, 1), "1")) 
DF$ts + hm(DF$offset)*signs 
#[1] "2015-09-02 04:06:17 EDT" "2015-09-02 03:06:17 EDT" 
#[3] "2015-09-02 16:36:17 EDT" "2015-09-02 17:06:17 EDT" 
#[5] "2015-09-02 17:36:17 EDT" 

Использование функции hm из пакета lubridate, мы можем преобразовать текстовые строки из offset колонки в час и минуту пролетами. Но поскольку положительные и отрицательные знаки игнорируются функцией, мы должны умножить переменную hour/minute на знак. Я предполагаю, что, как и в примере, для каждого смещения есть положительный или отрицательный знак.

0

Есть два основных способа:

Во-первых, на этапеформатирования применяется часовой пояс:

R> t <- Sys.time() 
R> sapply(c("America/New_York","America/Los_Angeles"),function(tz) format(t,tz=tz)) 
    America/New_York America/Los_Angeles 
"2015-09-02 15:34:28" "2015-09-02 12:34:28" 
R> 

три часа разница, как можно было бы ожидать.

Во-вторых, и это более хаком, просто сместится секунд:

R> sapply(seq(-60,60,60), function(dt) format(t+dt*60, tz="America/New_York")) 
[1] "2015-09-02 14:34:28" "2015-09-02 15:34:28" "2015-09-02 16:34:28" 
R> 

Это чище, чем ваш подход, как вам не нужно синтаксический анализ.

Наконец, контейнеры временного ряда, такие как xts, позволяют установить атрибут TZ, который я обычно делаю для реальных данных.

+0

Спасибо за ответ. Мои смещения временной шкалы всегда будут в формате смещений UTC, то есть он всегда будет в этом формате: '{+/-} {час}: {min}', например, '+11: 00',' -02: 30'. Есть ли функция для отображения '-04: 00' в' 'America/New_York''? – Boxuan

+0

Я думаю, вы неправильно поняли. В примере два я просто использую «любой» TZ для форматирования; ключом этого ответа являются числовые смещения. И да, у моего пакета RcppBDT есть некоторые помощники часового пояса из Boost Date_Time, которые могут там помочь. –

Смежные вопросы