将包含时区的日期字符串转换为 R 中的 POSIXct
Convert date string that contains time zone to POSIXct in 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")
我尝试使用 as.Date()
函数将此变量 Dates
读取到 R:
as.Date(Dates,format = "%a %b %d %H:%M:%S %Z %Y")
但进程失败,因为输入不支持 %Z
参数。整个矢量的时区不同。根据时区正确读取数据的替代方法是什么?
此解决方案需要一些简化假设。假设您的向量中有很多元素,最好的方法是使用时区偏移量数据库来确定每个时间是什么(在选定的语言环境中,例如 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(智利时间)可能与 GMT 相差 3-5 小时。
对于这个练习,我的代码只是从数据库中获取每个时区的第一个偏移量,并假设没有夏令时。如果您的工作不需要如此精确,这可能就足够了,但您应该以任何一种方式进行质量检查和验证您的工作。
另外请注意,此解决方案对于日期更改也应具有鲁棒性。例如,如果时间从凌晨 1 点调整到晚上 11 点,那么日期应该倒退一天。
我有一个包含这种格式的日期的向量(前 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")
我尝试使用 as.Date()
函数将此变量 Dates
读取到 R:
as.Date(Dates,format = "%a %b %d %H:%M:%S %Z %Y")
但进程失败,因为输入不支持 %Z
参数。整个矢量的时区不同。根据时区正确读取数据的替代方法是什么?
此解决方案需要一些简化假设。假设您的向量中有很多元素,最好的方法是使用时区偏移量数据库来确定每个时间是什么(在选定的语言环境中,例如 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(智利时间)可能与 GMT 相差 3-5 小时。
对于这个练习,我的代码只是从数据库中获取每个时区的第一个偏移量,并假设没有夏令时。如果您的工作不需要如此精确,这可能就足够了,但您应该以任何一种方式进行质量检查和验证您的工作。
另外请注意,此解决方案对于日期更改也应具有鲁棒性。例如,如果时间从凌晨 1 点调整到晚上 11 点,那么日期应该倒退一天。