将包含时区的日期字符串转换为R中的POSIXct

时间:2015-10-22 16:47:18

标签: r timezone as.date

我有一个带有这种格式的日期的矢量(前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函数将此变量as.Date()读取到R:

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

但是进程失败,因为输入中不支持%Z参数。整个矢量的时区不同。有关时区的正确读取数据有哪些替代方案?

1 个答案:

答案 0 :(得分:1)

此解决方案需要一些简化的假设。假设您的向量中有许多元素,最好的方法是使用时区偏移数据库来计算每次的时间(在选定的区域设置中,例如GMT)。我使用的时区数据是来自https://timezonedb.com/download

的timezone.csv文件
#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点调整到晚上11点,则日期应该恢复一天。