2015-10-22 3 views
0

У меня есть вектор с датами в этом формате (пример первых 6 строк):Преобразовать дату строка, которая содержит временную зону, чтобы POSIXct в R

Dates<-c(
    "Sun Oct 04 20:33:05 EEST 2015", 
    "Sun Oct 04 20:49:23 EEST 2015", 
    "Sun Oct 04 21:05:25 EEST 2015", 
    "Mon Sep 28 10:02:38 IDT 2015", 
    "Mon Sep 28 10:17:50 IDT 2015", 
    "Mon Sep 28 10:39:48 IDT 2015") 

Я пытался прочитать эту переменную Dates к R с помощью as.Date() функция:

as.Date(Dates,format = "%a %b %d %H:%M:%S %Z %Y") 

, но этот процесс не удалось, как %Z параметр не поддерживается на входе. Временные зоны различаются по всему вектору. Каковы альтернативы правильному считыванию данных в отношении часового пояса?

+0

«Временные часы», которые вы показываете, являются аббревиатурами, которые могут быть неоднозначными. Вам необходимо определить фактический часовой пояс, который они представляют (обычно указывается через страну/город). –

ответ

1

Это решение требует некоторых упрощающих предположений. Предполагая, что у вас много элементов в вашем векторе, наилучшим подходом является использование базы данных смещений часовых поясов, чтобы выяснить, что каждый раз (в выбранной локали, такой как GMT). Данные часового пояса я использовал файл timezone.csv из https://timezonedb.com/download

#Create sample data 
Dates<-c(
    "Sun Oct 04 20:33:05 EEST 2015", 
    "Sun Oct 04 20:49:23 EEST 2015", 
    "Sun Oct 04 21:05:25 EEST 2015", 
    "Mon Sep 28 10:02:38 IDT 2015", 
    "Mon Sep 28 10:17:50 IDT 2015", 
    "Mon Sep 28 10:39:48 IDT 2015") 

#separate timezone string from date/time info 
no_timezone <- paste(substr(Dates, 1, 19), substr(Dates, nchar(Dates)-3, nchar(Dates))) 
timezone <- as.data.frame(substr(Dates, 21, nchar(Dates)-5)) 
colnames(timezone) <- "abbreviation" 

#reference timezone database to get offsets from GMT 
timezone_db <- read.csv(file="timezonedb/timezone.csv", header=FALSE) 
colnames(timezone_db) <- c("zone_id", "abbreviation", "time_start", "gmt_offset", "dst") 
timezone_db <- timezone_db[timezone_db$dst == 0, ] 
timezone_db <- unique(timezone_db[,c("abbreviation", "gmt_offset")]) 
timezone_db <- timezone_db[!duplicated(timezone_db$abbreviation), ] 

#adjust all time to GMT 
time_adjust <- merge(timezone, timezone_db, all.x=TRUE, by="abbreviation") 
gmt_time <- strptime(no_timezone, format = "%a %b %d %H:%M:%S %Y", tz="GMT") 

#final data 
Dates_final <- gmt_time - time_adjust$gmt_offset 

В зависимости от того, насколько точной ваши данные должно быть, быть осторожным, чтобы настроить на летнее время, если это необходимо. Кроме того, я мало знаю о часовых поясах, но я заметил, что по некоторым причинам определенные часовые пояса могут иметь несколько смещений. В исходной базе данных CLT (чилийское время) может поменяться от 3-5 часов по Гринвичу.

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

Также обратите внимание, что это решение должно быть надежным и для изменения даты. Например, если время отрегулировано с 1 до 23 часов, то дата должна вернуться назад в один день.