r,write_csv将所有时间/日期更改为UTC

时间:2018-07-24 01:32:55

标签: r posixct readr

我发现了一个非常烦人的问题,想与社区分享。我已经找到了可以接受的解决方案(下面详细介绍),但是现在我有几个后续问题。我对时间戳和POSIX变量的了解有限,尤其是plyr,dplyr和readr如何处理这些信息。

当使用POSIX变量(又名,日期和时间戳)时,我发现来自readr的write_csv将这些变量更改为UTC时间。

我正在从API下载数据并保留时间戳。每次获取数据时,我都会将其绑定到现有文件并保存该文件。我的时区是MDT,我正在使用MDT时间请求数据,然后尝试将其绑定到UTC时间的文件,但时间不匹配...它变得混乱而令人沮丧。本质上,我要创建的漂亮的时间戳数据库正在变成一堆垃圾。

为解决此问题,我使用以下命令将POSIX时间列转换为字符列:

df.time <- as.character(df.time)

这使我可以将文件保存在与API返回给我的时间戳一致的时区中。

这使我想到以下一系列问题:

  1. 是否有一个程序可以跨时区联接POSIX变量?例如,如果它的中午是MDT,则是世界标准时间下午6点。我可以基于这些时间戳加入两个数据帧,而不必先将它们转换为相同的时区吗?
  2. 是否可以防止write_csv将POSIX变量更改为UTC?
  3. 是否有一个不更改POSIX变量的csv写函数?

编辑:我提供了一些我所谈论的示例数据:

> df1 <- as.data.frame(fromJSON("https://api.pro.coinbase.com/products/BTC-USD/candles?start=2018-07-23&12:57:00?stop=2018-07-23&19:34:58granularity=300"))
> colnames(df1) <- c("time", "low", "high", "open", "close", "volume")
> df1$time <- anytime(df1$time)
> df1Sort <- df1[order(df1$time),]
> head(df1Sort, 5)
                   time     low    high    open   close    volume
299 2018-07-23 16:13:00 7747.00 7747.01 7747.01 7747.01 9.2029168
298 2018-07-23 16:14:00 7743.17 7747.01 7747.00 7747.01 7.0205668
297 2018-07-23 16:15:00 7745.47 7745.73 7745.67 7745.73 0.9075707
296 2018-07-23 16:16:00 7745.72 7745.73 7745.72 7745.73 4.6715157
295 2018-07-23 16:17:00 7745.72 7745.73 7745.72 7745.72 2.4921921
> write_csv(df1Sort, "df1Sort.csv", col_names = TRUE)
> df2 <- read_csv("df1Sort.csv", col_names = TRUE)
Parsed with column specification:
cols(
  time = col_datetime(format = ""),
  low = col_double(),
  high = col_double(),
  open = col_double(),
  close = col_double(),
  volume = col_double()
)
> head(df2, 5)
# A tibble: 5 x 6
  time                  low  high  open close volume
  <dttm>              <dbl> <dbl> <dbl> <dbl>  <dbl>
1 2018-07-23 22:13:00  7747  7747  7747  7747  9.20 
2 2018-07-23 22:14:00  7743  7747  7747  7747  7.02 
3 2018-07-23 22:15:00  7745  7746  7746  7746  0.908
4 2018-07-23 22:16:00  7746  7746  7746  7746  4.67 
5 2018-07-23 22:17:00  7746  7746  7746  7746  2.49 

2 个答案:

答案 0 :(得分:1)

您似乎正在使用tidyverse中的库;您看过 lubridate 库吗?

as_date()的帮助文件可能会在此处帮助您在添加/加入数据之前将日期时间变量转换为所需的时区。

例如:

> dt_utc <- ymd_hms("2010-08-03 00:50:50")
> dt_utc
[1] "2010-08-03 00:50:50 UTC"

> as_datetime(dt_utc, tz = "Australia/Melbourne")
[1] "2010-08-03 10:50:50 AEST"

答案 1 :(得分:0)

  1. “是否有一个程序可以跨时区联接POSIX变量...而不必先将它们转换为相同时区?”

    也许?但是,如果是这样,他们几乎可以肯定只是在幕后转换为UTC并将其对您隐藏。我不知道R中有任何类似的东西。(data.table是我所知道的唯一一个可以加入除完全相等之外的任何东西的程序包,它不具有此功能。)您,我只是将所有内容都转换为一个时区-可能是UTC。

    有关最佳做法的更多阅读内容,this SQL-focused answer seems very good.

  2. “是否可以防止write_csv将POSIX变量更改为UTC?”

    不是内置的。 ?write_csv文档非常清楚:它没有列出任何选项,并说“ POSIXct的格式为ISO8601”。

  3. “是否有一个不更改POSIX变量的csv写函数?”

    当然,内置的write.csv不会更改为UTC(我认为它使用系统设置),并且data.table::fwrite提供了很多选项。如果您想控制日期的保存方式,我认为最好的选择是将日期转换为character的任何格式,然后任何编写函数都可以很好地处理它们。您应该查看?data.table::fwrite文档,它提供了很好的信息。他们警告说"write.csv"选项可能会很慢。


您的问题中应包括可复制的示例。这是一个:

t = as.POSIXct("2018-01-01 01:30:00", tz = "Africa/Addis_Ababa")
t
# [1] "2018-01-01 01:30:00 EAT"

d = data.frame(t)

library(readr)
write_csv(d, "tz_test.csv")
system("head tz_test.csv")
# 2017-12-31T22:30:00Z

library(data.table)
fwrite(d, "tz_test_dt.csv", dateTimeAs = "write.csv")
system("head tz_test_dt.csv")
# t
# 2018-01-01 01:30:00

write.csv(d, "tz_test_base.csv")
system("head tz_test_base.csv")
# "","t"
# "1",2018-01-01 01:30:00