【问题标题】:Character POSIXct Conversion in R causes wrong timezone values on daylight saving time transition (CEST/CET))R中的字符POSIXct转换导致夏令时转换(CEST / CET)时区值错误)
【发布时间】:2012-10-20 20:17:51
【问题描述】:

我在将 POSIXct 转换为字符并返回到 R 中的 POSIXct 时遇到问题。我运行以下代码:

time_seq_01 <- seq(as.POSIXct("2012-10-28 02:00:00"), by = 900, length.out = 10)
time_seq_02 <- as.character(time_seq_01)
time_seq_03 <- as.POSIXct(time_seq_02)

或同等的:

time_seq_01 <- seq(as.POSIXct("2012-10-28 02:00:00"), by = 900, length.out = 10)
time_seq_02 <- format(time_seq_01,usetz = TRUE)
time_seq_03 <- as.POSIXct(time_seq_02)

这是 2012 年夏令时从 中欧夏令时 (CEST)中欧夏令时 (CET) 的时间戳(10 月 2 日的最后一个星期日:00 - 03:00)。

当我调用这些元素时,我得到了

time_seq_01
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CEST"
[5] "2012-10-28 02:00:00 CET"  "2012-10-28 02:15:00 CET" 
[7] "2012-10-28 02:30:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 
time_seq_02
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CEST"
[5] "2012-10-28 02:00:00 CET"  "2012-10-28 02:15:00 CET" 
[7] "2012-10-28 02:30:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 
time_seq_03
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CET" 
[5] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[7] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 

POSIXct 序列的创建确实可以正常工作 (time_seq_01) 也可以转换为字符 (time_seq_02)。但是,从字符转换回 POSIXct 会产生错误的时区 (CET/CEST) 值 (time_seq_03)。当对这些元素进行排序时,可以清楚地看到这一点:

sort(time_seq_01)
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:15:00 CEST"
[3] "2012-10-28 02:30:00 CEST" "2012-10-28 02:45:00 CEST"
[5] "2012-10-28 02:00:00 CET"  "2012-10-28 02:15:00 CET" 
[7] "2012-10-28 02:30:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 
sort(time_seq_03)
[1] "2012-10-28 02:00:00 CEST" "2012-10-28 02:00:00 CEST"
[3] "2012-10-28 02:15:00 CEST" "2012-10-28 02:15:00 CEST"
[5] "2012-10-28 02:30:00 CEST" "2012-10-28 02:30:00 CEST"
[7] "2012-10-28 02:45:00 CET"  "2012-10-28 02:45:00 CET" 
[9] "2012-10-28 03:00:00 CET"  "2012-10-28 03:15:00 CET" 

这会导致许多问题,例如在按这些时间戳合并对象时。有没有办法克服这个问题?

我使用的系统:

Windows 7 64bit
R version 2.15.1 (2012-06-22)
Platform: x86_64-pc-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=German_Austria.1252  LC_CTYPE=German_Austria.1252   
[3] LC_MONETARY=German_Austria.1252 LC_NUMERIC=C                   
[5] LC_TIME=German_Austria.1252    
attached base packages:
[1] tools     stats     graphics  grDevices utils     datasets  methods 
[8] base     
other attached packages:
[1] pkgtools_0.1-3 roxygen2_2.2.2 digest_0.5.2   rj_1.1.0-4    
loaded via a namespace (and not attached):
[1] brew_1.0-6    plyr_1.7.1    rj.gd_1.1.0-1 stringr_0.6.1

【问题讨论】:

  • 你的sessionInfo() 是什么?你读过?POSIXct警告部分吗?
  • 我在上面的问题中添加了我的会话信息
  • 是否禁止在as.POSIXct 中使用tz 参数?这可以设置,允许您控制时区。
  • 除了@JoshuaUlrich 提到的警告部分,还有?as.POSIXct 的详细信息部分,它几乎完全解决了这个问题。
  • 按照建议,我查看了“?POSIXct”的推荐部分,并使用“Sys.setenv”设置了“TZ”变量。这并没有改变任何东西。我也在一台 linux 机器上构建了这个问题,得到了类似的结果。

标签: r posixct


【解决方案1】:

这是一个变通方法,从 POSIXctcharacter 再到 POSIXct 保留原来的夏令时状态。

Sys.setenv(TZ='Europe/Berlin') # to reproduce OP's example
time_seq_01 <- seq(as.POSIXct("2012-10-28 02:00:00"), by = 900, length.out = 10)
time_seq_02 <- format(time_seq_01,usetz = TRUE)

time_seq_02_lt <- as.POSIXlt(time_seq_02)
time_seq_02_lt$isdst <- as.POSIXlt(time_seq_01)$isdst
time_seq_03 <- as.POSIXct(time_seq_02_lt)

据我所知,R 对 string-to-datetime 的支持不包括在字符串中指定的 DST 标志。

【讨论】:

  • 感谢您的提示!仍然存在的一个问题是,实际上我没有可用的基本 POSIXct 序列,我必须从字符序列 (time_seq_02) 开始。所以我将time_seq_02_lt$isdst &lt;- as.POSIXlt(time_seq_01)$isdst 更改为time_seq_02_lt$isdst &lt;- grepl("CEST", time_seq_02) 这成功了。我认为的基本问题是,正如您所说,字符到 POSIXct 转换不支持 DST 标志。这样会容易很多。
猜你喜欢
  • 2022-11-13
  • 2020-08-18
  • 2012-10-31
  • 2018-04-30
  • 2022-01-11
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 2021-07-13
相关资源
最近更新 更多