R-UTC到当地时间给予奥尔森时区 [英] R - UTC to LOCAL time given Olson timezones

查看:188
本文介绍了R-UTC到当地时间给予奥尔森时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有1974 - 2013年的时间序列数据,其中包含datetimeUTC(YYYY-MM-DD hh:mm +0000)的列,以及Olson格式的时区的列(例如,加拿大/太平洋,加拿大/东部) 。我可以将整个UTCdatetime列转换为常见的时区,如下所示:

  dataset $ datetimeEST<  -  strptime(
数据集$ datetimeUTC,format =%Y-%m-%d%H:%M:%S%z,tz =加拿大/东部

如何将 datetimeUTC 转换为 datetimeLOCAL 给定每行相应的时区?



让我备份一下我有来自全国各地的数据(6个时区),格式为ISO8601表示,1974 - 2013年。时间戳是全年的地方标准时间(即使在该地区的平民时间观察到DST也忽略了DST)。我需要进行datetime计算,这在UTC时间可能是最安全的,所以这很简单。但是,我也需要提取特定民间时间段的数据,同时考虑到DST,并对该子集数据进行计算和绘图(例如,所有6个时区的高峰时段的所有数据)。



下面我计算的datetimeCLOCKTIME似乎正在做我想要的绘图,但是在进行datetime计算时给出错误的答案,因为它在我的时区中存储了datetime本地机器没有实际转换时间。 @thelatemail提供的解决方案是我正在寻找的,但是在2012年的测试数据集上,我无法使其在Windows中工作(见下文)。此外,我正在使用strptime转换为POXITlt,他的解决方案是POXITct。我是R的新手,所以任何帮助将无限感激。



测试数据集:

 数据集<  -  data.frame时间戳ISO8601 = c(2012-04-25T22:00:00-08:00,2012-04-25T22:15:00-08:00,2012-04-25T22:30:00-08:00 ,2012-04-25T22:45:00-08:00,2012-04-25T23:00:00-08:00,2012-04-25T23:15:00-08:00 2012-04-25T23:30:00-08:00,2012-04-25T23:45:00-08:00,2012-04-26T00:00:00-08:00,2012 -04-26T00:15:00-08:00,2012-04-26T00:30:00-08:00,2012-04-26T00:45:00-08:00,2012-04 -26T01:00:00-08:00,2012-04-26T01:15:00-08:00,2012-04-26T01:30:00-08:00,2012-04-26T01 :45:00-08:00,2012-04-26T02:00:00-08:00,2012-04-25T22:00:00-03:30,2012-04-25T22:15 :00-03:30,2012-04-25T22:30:00-03:30,2012-04-25T22:45:00-03:30,2012-04-25T23:00:00 -03:30,2012-04-25T23:15:00-03:30,2012-04-25T23:30:00-03:30,2012-04-25T23:45:00-03 :30,2012-04-26T00:00:00-03:30,2012-04-26T00:15:00-03:30,2012-04-26T00:30:00-03:30 ,2012-04-26T00:45:00-03:30,2012-04-26T01:00:00-03:30,2012-04-26T01:15:00-03:30 2012-04-26T01:30:00- 03:30,2012-04-26T01:45:00-03:30,2012-04-26T02:00:00-03:30),olson = c(加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋 加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋,加拿大/太平洋 加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰 /纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰,加拿大/纽芬兰 (0,0,1,2,5,11,17,19,20,19,17,11,5,2,1,0,0,-3,-3,-2,-1,2,8 ,14,16,17,16,14,8,2,-1,-2,-3,-3),stringsAsFactors = FALSE)

从UTC偏移中删除:。 (R是期望UTC偏移的格式nnnn):

  dataset $ timestampR<  -  paste(substr(dataset $ timestampISO8601, 1,22),substr(数据集$ timestampISO8601,24,25),sep =)

当转换为UTC时间时,R默认为-ve用于UTC偏移量,使时间戳中的-off偏移量为正值:

 数据集$ datetimeUTC<  -  strptime(dataset $ timestampR,format =%Y-%m-%dT%H:%M:%S%z,tz =UTC)

当转换为MACHINE这样的时间时,R读取输入时间并将其转换为本地计算机时区的时间 - 在我的情况下,这是加拿大/东部:

  dataset $ datetimeMACHINE<  -  strptime(dataset $ timestampR,format =%Y-%m - %dT%H:%M:%S%z)

当转换为CLOCKTIME时间这样,R读取输入时间并分配本地机器的时区(目前在我的机器上的EDT),而不需要任何时间nversions:

  dataset $ datetimeCLOCKTIME<  -  strptime(dataset $ timestampR,format =%Y-%m-%dT% H:%M:%S)

查看数据集的结构:

  str(dataset)

绘图行为不同

  library(ggplot2)
qplot(data = dataset,x = datetimeUTC,y =值)
qplot(data = dataset,x = datetimeMACHINE,y = value)
qplot(data = dataset,x = datetimeCLOCKTIME,y = value)
/ pre>

计算结果不同。 datetimeCLOCKTIME计算结果不正确:

  range(dataset $ datetimeUTC)
range(dataset $ datetimeMACHINE)
范围(数据集$ datetimeCLOCKTIME)

dataset $ datetimeUTC [34] - 数据集$ datetimeUTC [1]
dataset $ datetimeMACHINE [34] - dataset $ datetimeMACHINE [1]
dataset $ datetimeCLOCKTIME [34] - 数据集$ datetimeCLOCKTIME [1]


解决方案

您可以来回格式来获取字符格式的本地时间表示。例如:

 数据集<  -  data.frame(
datetimeUTC = c(2014-01-01 00: 00 +0000,2014-01-01 00:00 +0000),
olson = c(加拿大/东部,加拿大/太平洋),
stringsAsFactors = FALSE


#datetimeUTC olson
#1 2014-01-01 00:00 +0000加拿大/东部
#2 2014-01-01 00:00 +0000加拿大/太平洋

dataset $ localtime< - with(dataset,
mapply(function(dt,ol)format)(
as.POSIXct(dt,%Y-%m- %d%H:%M%z,tz = ol),
%Y-%m-%d%H:%M%z),
datetimeUTC,olson



#datetimeUTC olson localtime
#1 2014-01-01 00:00 +0000加拿大/东部2013-12-31 19:00 -0500
#2 2014-01-01 00:00 +0000加拿大/太平洋2013-12-31 16:00 -0800


I have time series data from 1974-2013 with a column for datetimeUTC (YYYY-MM-DD hh:mm +0000), and a column for the timezones in Olson format (e.g., Canada/Pacific, Canada/Eastern). I can convert the whole UTCdatetime column to a common timezone like this:

dataset$datetimeEST <- strptime(
  dataset$datetimeUTC, format="%Y-%m-%d %H:%M:%S%z", tz="Canada/Eastern"
)  

How do I convert datetimeUTC to datetimeLOCAL, given the corresponding timezone in each row?

Let me back up a bit. I have data from across the country (6 timezones) formatted in ISO8601 representation for 1974-2013. The timestamps are in local standard time throughout the year (i.e. DST is disregarded even if civilian time in the region observes DST). I need to do datetime calculations which are probably safest to do in UTC time, so that's easy. But, I also need to pull data for specific civil time periods, taking into account DST, and do calculations and plots (e.g., all the data for rush hour at locations across all 6 timezones) for that subsetted data.

The datetimeCLOCKTIME that I calculated below appears to be doing what I want for plotting, but gives the wrong answer when doing datetime calculations because it stored the datetime in the timezone of my local machine without having actually converted the time. The solution offered by @thelatemail is what I'm looking for, but I haven't been able to get it to work in Windows on the test dataset for 2012 (see below). Also, I was using strptime which converts to POXITlt, and his solution is in POXITct. I'm new to R, so any help would be infinitely appreciated.

Test dataset:

    dataset <- data.frame (timestampISO8601 = c("2012-04-25T22:00:00-08:00","2012-04-25T22:15:00-08:00","2012-04-25T22:30:00-08:00","2012-04-25T22:45:00-08:00","2012-04-25T23:00:00-08:00","2012-04-25T23:15:00-08:00","2012-04-25T23:30:00-08:00","2012-04-25T23:45:00-08:00","2012-04-26T00:00:00-08:00","2012-04-26T00:15:00-08:00","2012-04-26T00:30:00-08:00","2012-04-26T00:45:00-08:00","2012-04-26T01:00:00-08:00","2012-04-26T01:15:00-08:00","2012-04-26T01:30:00-08:00","2012-04-26T01:45:00-08:00","2012-04-26T02:00:00-08:00","2012-04-25T22:00:00-03:30","2012-04-25T22:15:00-03:30","2012-04-25T22:30:00-03:30","2012-04-25T22:45:00-03:30","2012-04-25T23:00:00-03:30","2012-04-25T23:15:00-03:30","2012-04-25T23:30:00-03:30","2012-04-25T23:45:00-03:30","2012-04-26T00:00:00-03:30","2012-04-26T00:15:00-03:30","2012-04-26T00:30:00-03:30","2012-04-26T00:45:00-03:30","2012-04-26T01:00:00-03:30","2012-04-26T01:15:00-03:30","2012-04-26T01:30:00-03:30","2012-04-26T01:45:00-03:30","2012-04-26T02:00:00-03:30"), olson = c("Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Pacific","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland","Canada/Newfoundland"), value = c(0,0,1,2,5,11,17,19,20,19,17,11,5,2,1,0,0,-3,-3,-2,-1,2,8,14,16,17,16,14,8,2,-1,-2,-3,-3), stringsAsFactors=FALSE)

Remove the ":" from the UTC offset. (R is expecting the format nnnn for the UTC offset):

    dataset$timestampR<- paste(substr(dataset$timestampISO8601,1,22),substr(dataset$timestampISO8601,24,25),sep="")

When converting to UTC time, R defaults to -ve for the UTC offset, making -ve offsets in the timestamps positive:

    dataset$datetimeUTC <- strptime(dataset$timestampR, format="%Y-%m-%dT%H:%M:%S%z", tz="UTC")

When converting to MACHINE time like this, R reads the input time and converts it to the time in the timezone of the local machine - in my case, this is Canada/Eastern:

    dataset$datetimeMACHINE <- strptime(dataset$timestampR, format="%Y-%m-%dT%H:%M:%S%z")

When converting to CLOCKTIME time like this, R reads the input time and assigns the time zone of the local machine (currently EDT on my machine) without doing any time conversions:

    dataset$datetimeCLOCKTIME <- strptime(dataset$timestampR,format="%Y-%m-%dT%H:%M:%S")

See the structure of the dataset:

    str(dataset)  

Plotting behaviours are different

    library(ggplot2)
    qplot(data=dataset,x=datetimeUTC,y=value)
    qplot(data=dataset,x=datetimeMACHINE,y=value)
    qplot(data=dataset,x=datetimeCLOCKTIME,y=value)

Calculation results differ. Incorrect calculation result for datetimeCLOCKTIME:

    range (dataset$datetimeUTC)
    range (dataset$datetimeMACHINE)
    range (dataset$datetimeCLOCKTIME)

    dataset$datetimeUTC[34] - dataset$datetimeUTC[1]
    dataset$datetimeMACHINE[34] - dataset$datetimeMACHINE[1]
    dataset$datetimeCLOCKTIME[34] - dataset$datetimeCLOCKTIME[1]

解决方案

You could format back and forth a bit to get a local time representation in a character format. E.g.:

dataset <- data.frame(
  datetimeUTC=c("2014-01-01 00:00 +0000","2014-01-01 00:00 +0000"),
  olson=c("Canada/Eastern", "Canada/Pacific"),
  stringsAsFactors=FALSE
)

#             datetimeUTC          olson
#1 2014-01-01 00:00 +0000 Canada/Eastern
#2 2014-01-01 00:00 +0000 Canada/Pacific

dataset$localtime <- with(dataset, 
     mapply(function(dt,ol) format(
              as.POSIXct(dt,"%Y-%m-%d %H:%M %z",tz=ol),
              "%Y-%m-%d %H:%M %z"), 
              datetimeUTC, olson
            )
     )

#             datetimeUTC          olson              localtime
#1 2014-01-01 00:00 +0000 Canada/Eastern 2013-12-31 19:00 -0500
#2 2014-01-01 00:00 +0000 Canada/Pacific 2013-12-31 16:00 -0800

这篇关于R-UTC到当地时间给予奥尔森时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆