Преобразование строки даты, содержащей часовой пояс, в POSIXct в R

У меня есть вектор с датами в таком формате (пример первых 6 строк):

 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 не поддерживается на входе. Часовые пояса различаются по всему вектору. Каковы альтернативы правильному чтению данных относительно часового пояса?


person GegznaV    schedule 22.10.2015    source источник
comment
Показанные вами часовые пояса являются аббревиатурами, которые потенциально могут быть двусмысленными. Вам необходимо определить фактический часовой пояс, который они представляют (обычно указывается через Country/City).   -  person Joshua Ulrich    schedule 22.10.2015


Ответы (1)


Это решение требует некоторых упрощающих предположений. Предполагая, что у вас есть много элементов в вашем векторе, лучший подход — использовать базу данных смещений часовых поясов, чтобы выяснить, что такое каждый раз (в выбранной локали, например, по Гринвичу). Я использовал данные часового пояса из файла 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 (чилийское время) по какой-то причине может отличаться от GMT на 3-5 часов.

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

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

person JFu    schedule 22.10.2015