2016-12-16 128 views
0

我想告訴r我的數據在UTC時區,以便我可以將它們移至America/New_York。但是當我使用indexTZ()它改變了時間。如何更改xts中的時區

我希望UTC時間16:00成爲紐約時間的12:00。

test = read.zoo(paste0(datadir,"test_.csv"), 
        index = 1,FUN = as.POSIXct, header = T, sep = ",") 
    test = as.xts(test) 
    head(test) 


    > QQQ.Open QQQ.High QQQ.Low QQQ.Close QQQ.Volume 
    > 
    > 2016-09-10 16:38:00 4665.75 4665.75 4665.75 4665.75   1 
    > 2016-09-11 14:13:00 4665.75 4665.75 4665.75 4665.75   1 
    > 2016-09-11 22:01:00 4661.25 4667.25 4657.25 4666.75  932 
    > 2016-09-11 22:02:00 4666.75 4667.25 4663.25 4665.00  174 
    > 2016-09-11 22:03:00 4665.00 4667.00 4665.00 4666.50   66 


    indexTZ(test)<- "UTC" 
    head(test) 

        QQQ.Open QQQ.High QQQ.Low QQQ.Close QQQ.Volume 
2016-09-10 20:38:00 4665.75 4665.75 4665.75 4665.75   1 
2016-09-11 18:13:00 4665.75 4665.75 4665.75 4665.75   1 
2016-09-12 02:01:00 4661.25 4667.25 4657.25 4666.75  932 
2016-09-12 02:02:00 4666.75 4667.25 4663.25 4665.00  174 
2016-09-12 02:03:00 4665.00 4667.00 4665.00 4666.50   66 
Warning message: 
timezone of object (UTC) is different than current timezone(). 


> test_dt$hour1 = strftime(test_dt$index, format = "%H", tz = "America/New_York") 

> test_dt$hour2 = strftime(test_dt$index, format = "%H", tz = "UTC") 

> table(test_dt$hour1) 

14 16 22 
1 1 3 

> table(test_dt$hour2) 

02 18 20 
3 1 1 

回答

2

移位時區有點棘手。您需要先退後一步,並意識到實際存儲的時間是表示絕對時間的數字(自1970年1月1日以來的秒數)。即看我怎麼代表同一時間點(「時代」)作爲在紐約和莫斯科當地時間:

R> format(as.POSIXct(0,origin="1970-01-01"), tz="UTC") 
[1] "1970-01-01" 
R> format(as.POSIXct(0,origin="1970-01-01"), tz="America/New_York") 
[1] "1969-12-31 19:00:00" 
R> format(as.POSIXct(0,origin="1970-01-01"), tz="Europe/Moscow") 
[1] "1970-01-01 03:00:00" 
R> 

現在,你已經存儲的時間很可能被解析的當地時間。那就是他們包含一個偏移商店作爲時區。通過改變你只是移動相對於之前的時間:

R> as.POSIXct("2016-09-10 16:38:00") # CDT as I am in Chicago 
[1] "2016-09-10 16:38:00 CDT" 
R> format(as.POSIXct("2016-09-10 16:38:00"), tz="America/New_York") 
[1] "2016-09-10 17:38:00" 
R> format(as.POSIXct("2016-09-10 16:38:00"), tz="America/Los_Angeles") 
[1] "2016-09-10 14:38:00" 
R> 

所以我正確地理解你的問題,你需要做兩件事情:「撤消」你有本地時間,然後移動到所需的時區。

我也爲此寫了一個幫手 - 在RcppCCTZ包中。下面是toTz()功能一個例子:

R> example(toTz) 

toTzR> toTz(Sys.time(), "America/New_York", "Europe/London") 
[1] "2016-12-17 01:04:14.184086 CST" 

toTzR> # this redoes the 'Armstrong on the moon in NYC and Sydney' example 
toTzR> # note that the default print method will print the return object in _your local time_ 
toTzR> toTz(ISOdatetime(1969,7,20,22,56,0,tz="UTC"), "America/New_York", "Australia/Sydney", verbose=TRUE) 
1969-07-20 22:56:00 -0400 
1969-07-21 12:56:00 +1000 
[1] "1969-07-20 21:56:00 CDT" 

toTzR> # whereas explicitly formating for Sydney time does the right thing 
toTzR> format(toTz(ISOdatetime(1969,7,20,22,56,0,tz="UTC"), 
toTz+    "America/New_York", "Australia/Sydney", verbose=TRUE), 
toTz+  tz="Australia/Sydney") 
1969-07-20 22:56:00 -0400 
1969-07-21 12:56:00 +1000 
[1] "1969-07-21 12:56:00" 

這也說明了確保您打印到所需的時區中增添了難度 - 僅在第二個例子中顯示了正確的悉尼的時刻,我們明確告訴format()使用它。

所以要回你的例子:

R> x <- xts(1:2, Sys.time() + 0:1) 
R> x 
          [,1] 
2016-12-16 20:13:43.29767 1 
2016-12-16 20:13:44.29767 2 
R> tzone(x) <- "America/New_York" 
R> x 
          [,1] 
2016-12-16 21:13:43.29767 1 
2016-12-16 21:13:44.29767 2 
Warning message: 
timezone of object (America/New_York) is different than current timezone(). 
R> index(x) <- index(x) - 60*60 # dirty method, last resort 
R> x 
          [,1] 
2016-12-16 20:13:43.29767 1 
2016-12-16 20:13:44.29767 2 
Warning message: 
timezone of object (America/New_York) is different than current timezone(). 
R> tzone(x) 
       TZ 
"America/New_York" 
R> 

所以我明確60分鐘改變數字值佔的事實,我一小時轉移時間(從芝加哥,我的本地時間,紐約)。

2

當您可能應該將時區指定爲「UTC」時,您的數據可能已加載爲「America/New_York」時間。 (您可以在時區參數傳遞的直通參數FUN=POSIXct。)

再現原來的情況:

data <- " 2016-09-10 16:38:00 4665.75 4665.75 4665.75 4665.75   1 
2016-09-11 14:13:00 4665.75 4665.75 4665.75 4665.75   1 
2016-09-11 22:01:00 4661.25 4667.25 4657.25 4666.75  932 
2016-09-11 22:02:00 4666.75 4667.25 4663.25 4665.00  174 
2016-09-11 22:03:00 4665.00 4667.00 4665.00 4666.50   66" 

data = read.table(text = data, 
        col.names = c("date", "time", "Open" , "High", "Low", "Close", "Volume") 
       ) 
# assumes data is loaded in America/New_York time zone 
x_data <- xts(order.by = as.POSIXct(paste(data$date, data$time), tz = "America/New_York"), data[3:NCOL(data)]) 


x_data 
# Open High  Low Close Volume 
# 2016-09-10 16:38:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-11 14:13:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-11 22:01:00 4661.25 4667.25 4657.25 4666.75 932 
# 2016-09-11 22:02:00 4666.75 4667.25 4663.25 4665.00 174 
# 2016-09-11 22:03:00 4665.00 4667.00 4665.00 4666.50  66 

indexTZ(x_data) <- "UTC" 

# This reproduces your situation (problem): 
head(x_data) 
# Open High  Low Close Volume 
# 2016-09-10 20:38:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-11 18:13:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-12 02:01:00 4661.25 4667.25 4657.25 4666.75 932 
# 2016-09-12 02:02:00 4666.75 4667.25 4663.25 4665.00 174 
# 2016-09-12 02:03:00 4665.00 4667.00 4665.00 4666.50  66 


# This is what you probably wanted to do. Set the initial timezone to "UTC" when you loaded the data into R and created your `POSIXct` objects. 

x_data <- xts(order.by = as.POSIXct(paste(data$date, data$time), tz = "UTC"), data[3:NCOL(data)]) 
head(x_data) 
# Open High  Low Close Volume 
# 2016-09-10 16:38:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-11 14:13:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-11 22:01:00 4661.25 4667.25 4657.25 4666.75 932 
# 2016-09-11 22:02:00 4666.75 4667.25 4663.25 4665.00 174 
# 2016-09-11 22:03:00 4665.00 4667.00 4665.00 4666.50  66 
indexTZ(x_data) <- "America/New_York" 
# Now you get your desired outcome: 
head(x_data) 
# Open High  Low Close Volume 
# 2016-09-10 12:38:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-11 10:13:00 4665.75 4665.75 4665.75 4665.75  1 
# 2016-09-11 18:01:00 4661.25 4667.25 4657.25 4666.75 932 
# 2016-09-11 18:02:00 4666.75 4667.25 4663.25 4665.00 174 
# 2016-09-11 18:03:00 4665.00 4667.00 4665.00 4666.50  66 
0

啊哈,是的,答案是創建XTS與正確的對象時區:

如:

S = as.xts(test, tz = "UTC")