检查是否在GMT中,然后在GMT - R - 循环中转换为当地时间

时间:2017-11-17 22:38:04

标签: r lubridate posixct

如果日期时间 是GMT ,然后将其转换为 代表当地时间 。由于人们建议重复,我希望将 从GMT转换为本地时间 ,但更重要的是,特别想要检查是否需要进行转换。我正在使用lubridatedplyrzoostringr

以此示例数据为例(我的数据位于nums和POSXIct格式的更大数据框中):

store 1000df数据框的列为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

从格林威治标准时间转换为EDT或MST后,夏令时会占多少?

先谢谢你,

2 个答案:

答案 0 :(得分:1)

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。我喜欢rubridate功能&#34; ymd_hms&#34;在这里,因为它非常灵活。您还可以使用参数&#34; tz&#34;来设置时区的内容。这将返回时间在您当前的时区。例如,我在西雅图,所以这会为我返回PST的等效时间。我非常确定lubridate可以说明夏令时。 (我很难得到这个,因此选择&#34; for&#34;循环。我确定其他人可以在没有它的情况下实现这一点。)

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的同一列中创建多个时区。

答案 1 :(得分:1)

让我们首先创建一个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)

您的功能的一个问题是您使用错误的语法来检查字符&#34; GMT&#34;在你的字符串中。你不想要%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部分是否正在返回你想要的东西;我可以看到不使用非标准化的时区信息。