检查是否在格林威治标准时间,然后在格林威治标准时间转换为当地时间 - R - 循环
check if in GMT, then convert to local time in in GMT - R - looping
我发现了一百万篇关于从格林威治标准时间转换为当地时间的帖子,但没有一个首先检查如果日期-时间是GMT,然后转换成它的代表当地时间。由于人们建议复制,我希望将 从 GMT 转换为当地时间 ,但更重要的是, 特别想检查是否需要进行转换。我正在使用 lubridate
、dplyr
、zoo
和 stringr
。
以这个示例数据为例(我的数据在一个更大的 nums 和 POSXIct 格式的数据框中):
对于 store 1000
,df
数据框具有列 Time
:
Time<-c("2017-02-02 06:05:00 GMT", "2017-02-04 00:06:10 GMT", "2017-02-05 00:06:15 GMT")
df<-as.data.frame(Time)
time_zone_info
如下:
x<-1000
timezone<-"US/Eastern"
time_zone_info<-cbind(x,timezone)
time_zone_info<-as.data.frame(time_zone_info)
我目前的尝试如下:
correct_to_local_time<-function(df){
if("GMT" %in% df$Time){
df$Time<-as.POSIXct(df$Time, tz ="GMT",usetz=TRUE)
df$Time<-with_tz(df$Time,tz=time_zone_info$timezone)
}
else{
as.POSIXct(df$Time)}
}
correct_to_local_time(df)
这给了我以下计算不正确的(它应该是 1:05:00EDT、01:10:00EDT 等,但它确实将 GMT 更改为 EDT,所以我很困惑.. .):
Time
2017-02-02 06:05:00 EDT
2017-02-02 06:10:00 EDT
2017-02-02 06:10:00 EDT
理想情况下,我想要这样的东西:
Local Time
2017-02-02 01:05:00 EDT
2017-02-04 01:10:00 EDT
2017-02-05 01:15:00 EDT
从 GMT 转换为 EDT 或 MST 后,夏令时是否考虑在内?
提前谢谢大家
软件包 lubridate
可能可以帮助您。
require(lubridate)
dfTime<-c("2017-02-02 06:05:00 GMT",
"2017-02-04 00:06:00 New_York",
"2017-02-05 00:06:00 US/Mountain")
dfStore <-c(1000, 2000, 3000)
dftimeZone<-c("US/Eastern", "US/Eastern", "US/Mountain")
time_zone_info <- data.frame(Store = dfStore,
Time = dfTime,
Timezone = dftimeZone,
stringsAsFactors = FALSE)
首先,检查您的所有时区是否都在系统识别的时区列表内。 (我不确定。)
all(time_zone_info$Timezone %in% OlsonNames())
好的,很好。
接下来,将你的时间字符串转换成POSIXct。我喜欢这里的 lubridate 函数 "ymd_hms",因为它非常灵活。您也可以使用参数 "tz" 设置时区。这 returns 时间 在您当前的时区 。例如,我在西雅图,所以这个 returns 对我来说是太平洋标准时间的等效时间。我很确定 lubridate 会考虑夏令时。 (我很难让它适用,因此选择了 "for" 循环。不过,我相信其他人可以在没有它的情况下做到这一点。)
time_zone_info$Time2 <- as.POSIXct(NA)
for(i in 1:nrow(time_zone_info)){
time_zone_info$Time2[i] <- ymd_hms(time_zone_info$Time[i],
tz = time_zone_info$Timezone[i])
}
time_zone_info$Time2
中的所有内容都将处于同一时区,我相信这是为了方便比较而设计的。很难让R在data.frame的同一列中制作多个时区。
让我们首先制作一个 data.frame ,它更接近您实际使用的内容,并且比您提交一行的单列 data.frame 更容易使用到你的功能。
df <- data.frame(
Store = c(1000, 2000, 3000),
Time = c("2017-02-02 06:05:00 GMT",
"2017-02-04 00:06:10 GMT",
"2017-02-05 00:06:15 GMT"),
stringsAsFactors = FALSE)
同样,让我们更简洁地编写另一个 data.frame 并制作 类 字符串而不是因子,因为因子会使您出错。 (这与其说是要求,不如说是偏好。)
time_zone_info <- data.frame(
Store = 1000,
timezone = "US/Eastern",
stringsAsFactors = FALSE)
您的函数存在一个问题,即您使用错误的语法来检查字符 "GMT" 是否在您的字符串中。你不想要 %in%
;你想要 stringr
方便的 str_detect
功能。
此外,与其输入一个 data.frame 并输出一个 data.frame,这在您当前应用它时可能会很棘手,让我们设计函数以便输入是单个字符串并且输出是单个字符串,更易于使用。
require(stringr)
require(lubridate)
correct_to_local_time<-function(InputTime){
if(str_detect(InputTime, "GMT")){
GMTTime <- as.POSIXct(InputTime, tz = "GMT", usetz = TRUE)
OutputTime <- with_tz(GMTTime, tz = time_zone_info$timezone)
} else {
OutputTime <- as.POSIXct(InputTime)}
return(OutputTime)
}
correct_to_local_time(df$Time[1])
如果我是你,我也会严格检查你函数的 else
部分是否返回你想要的;我可以看到不使用非标准化时区信息。
我发现了一百万篇关于从格林威治标准时间转换为当地时间的帖子,但没有一个首先检查如果日期-时间是GMT,然后转换成它的代表当地时间。由于人们建议复制,我希望将 从 GMT 转换为当地时间 ,但更重要的是, 特别想检查是否需要进行转换。我正在使用 lubridate
、dplyr
、zoo
和 stringr
。
以这个示例数据为例(我的数据在一个更大的 nums 和 POSXIct 格式的数据框中):
对于 store 1000
,df
数据框具有列 Time
:
Time<-c("2017-02-02 06:05:00 GMT", "2017-02-04 00:06:10 GMT", "2017-02-05 00:06:15 GMT")
df<-as.data.frame(Time)
time_zone_info
如下:
x<-1000
timezone<-"US/Eastern"
time_zone_info<-cbind(x,timezone)
time_zone_info<-as.data.frame(time_zone_info)
我目前的尝试如下:
correct_to_local_time<-function(df){
if("GMT" %in% df$Time){
df$Time<-as.POSIXct(df$Time, tz ="GMT",usetz=TRUE)
df$Time<-with_tz(df$Time,tz=time_zone_info$timezone)
}
else{
as.POSIXct(df$Time)}
}
correct_to_local_time(df)
这给了我以下计算不正确的(它应该是 1:05:00EDT、01:10:00EDT 等,但它确实将 GMT 更改为 EDT,所以我很困惑.. .):
Time
2017-02-02 06:05:00 EDT
2017-02-02 06:10:00 EDT
2017-02-02 06:10:00 EDT
理想情况下,我想要这样的东西:
Local Time
2017-02-02 01:05:00 EDT
2017-02-04 01:10:00 EDT
2017-02-05 01:15:00 EDT
从 GMT 转换为 EDT 或 MST 后,夏令时是否考虑在内?
提前谢谢大家
软件包 lubridate
可能可以帮助您。
require(lubridate)
dfTime<-c("2017-02-02 06:05:00 GMT",
"2017-02-04 00:06:00 New_York",
"2017-02-05 00:06:00 US/Mountain")
dfStore <-c(1000, 2000, 3000)
dftimeZone<-c("US/Eastern", "US/Eastern", "US/Mountain")
time_zone_info <- data.frame(Store = dfStore,
Time = dfTime,
Timezone = dftimeZone,
stringsAsFactors = FALSE)
首先,检查您的所有时区是否都在系统识别的时区列表内。 (我不确定。)
all(time_zone_info$Timezone %in% OlsonNames())
好的,很好。
接下来,将你的时间字符串转换成POSIXct。我喜欢这里的 lubridate 函数 "ymd_hms",因为它非常灵活。您也可以使用参数 "tz" 设置时区。这 returns 时间 在您当前的时区 。例如,我在西雅图,所以这个 returns 对我来说是太平洋标准时间的等效时间。我很确定 lubridate 会考虑夏令时。 (我很难让它适用,因此选择了 "for" 循环。不过,我相信其他人可以在没有它的情况下做到这一点。)
time_zone_info$Time2 <- as.POSIXct(NA)
for(i in 1:nrow(time_zone_info)){
time_zone_info$Time2[i] <- ymd_hms(time_zone_info$Time[i],
tz = time_zone_info$Timezone[i])
}
time_zone_info$Time2
中的所有内容都将处于同一时区,我相信这是为了方便比较而设计的。很难让R在data.frame的同一列中制作多个时区。
让我们首先制作一个 data.frame ,它更接近您实际使用的内容,并且比您提交一行的单列 data.frame 更容易使用到你的功能。
df <- data.frame(
Store = c(1000, 2000, 3000),
Time = c("2017-02-02 06:05:00 GMT",
"2017-02-04 00:06:10 GMT",
"2017-02-05 00:06:15 GMT"),
stringsAsFactors = FALSE)
同样,让我们更简洁地编写另一个 data.frame 并制作 类 字符串而不是因子,因为因子会使您出错。 (这与其说是要求,不如说是偏好。)
time_zone_info <- data.frame(
Store = 1000,
timezone = "US/Eastern",
stringsAsFactors = FALSE)
您的函数存在一个问题,即您使用错误的语法来检查字符 "GMT" 是否在您的字符串中。你不想要 %in%
;你想要 stringr
方便的 str_detect
功能。
此外,与其输入一个 data.frame 并输出一个 data.frame,这在您当前应用它时可能会很棘手,让我们设计函数以便输入是单个字符串并且输出是单个字符串,更易于使用。
require(stringr)
require(lubridate)
correct_to_local_time<-function(InputTime){
if(str_detect(InputTime, "GMT")){
GMTTime <- as.POSIXct(InputTime, tz = "GMT", usetz = TRUE)
OutputTime <- with_tz(GMTTime, tz = time_zone_info$timezone)
} else {
OutputTime <- as.POSIXct(InputTime)}
return(OutputTime)
}
correct_to_local_time(df$Time[1])
如果我是你,我也会严格检查你函数的 else
部分是否返回你想要的;我可以看到不使用非标准化时区信息。