两种带有时间格式且未指定格式的紧密时间字符串的POSIX行为都很奇怪

时间:2019-01-10 15:15:13

标签: r posix posixct

我不完全了解将数据和时间字符串转换为POSIX对象的行为。例如,我有两个字符串的向量,分别代表日期和时间。不指定格式的转换将忽略时间部分,并将时区设置为IST:

as.POSIXct(c('2017-03-24 02:59:59', '2017-03-24 03:00:00'))
[1] "2017-03-24 IST" "2017-03-24 IST"

但是,当我指定格式时,它设置为不同的时区,并且对于小时数为'2'的字符串失败,但是如果时间是第二个则不会。

as.POSIXct(c('2017-03-24 02:59:59', '2017-03-24 03:00:00'), format="%Y-%m-%d %H:%M:%OS")
[1] NA "2017-03-24 03:00:00 IDT"

三个问题:

  1. 为什么两行之间的时区不同
  2. 为什么没有给出任何格式时会忽略时间部分。
  3. 为什么在指定格式后无法转换第一个字符串?

1 个答案:

答案 0 :(得分:3)

  
      
  1. 为什么两行之间的时区不同
  2.   

如评论中所述,由于夏令时而有所不同。由于您未在对as.POSIXct的调用中包括该区域,因此容易出现许多问题。只要有可能,请明确时区。这是一个无懈可击的时刻:如果您知道它(并且它不是字符串的一部分),则从不假定它将被正确推断。以我的经验,它会把它弄错,以至于变得很烦人,而且很难发现,发现和修复。


  
      
  1. 为什么没有给出格式时会忽略时间部分
  2.   

虽然看起来像,但没有。这只是打印而不是存储方式的症状。 (这在R的许多功能中很常见,例如,它如何显示pi仅带有少数小数位,而它肯定存储了更多的小数。如果没有这种“表示与实际精度”模型,R的控制台将不必要地总是充满小数位等等。)

如果我将您的代码更新为明确包含区域:

as.POSIXct(c('2017-03-24 02:59:59', '2017-03-24 03:00:00'), tz="Israel")
# [1] "2017-03-24 IST" "2017-03-24 IST"
as.POSIXct(c('2017-03-24 02:59:59', '2017-03-24 03:00:00'), tz="Israel") + 1
# [1] "2017-03-24 00:00:01 IST" "2017-03-24 00:00:01 IST"

在第二种情况下,我将时间增加了一秒,您会看到时间已经到了。您可以查看内部结构,以不同的方式查看它:

dput(as.POSIXct(c('2017-03-24 02:59:59', '2017-03-24 03:00:00'), tz="Israel"))
# structure(c(1490306400, 1490306400), class = c("POSIXct", "POSIXt"
# ), tzone = "Israel")
dput(as.POSIXct(c('2017-03-24 02:59:59', '2017-03-24 03:00:00'), tz="Israel")+1)
# structure(c(1490306401, 1490306401), tzone = "Israel", class = c("POSIXct", 
# "POSIXt"))

时间存储为浮点数和特殊类。在这两者之间(不加1秒),您可以看到这些数字是一一对应的。

第三种确认方法是采用“缺少时间”的posix对象并显式打印到某物(不再是POSIXct,而只是用于演示):

a <- as.POSIXct(c('2017-03-24 02:59:59', '2017-03-24 03:00:00'), tz="Israel")
a
# [1] "2017-03-24 IST" "2017-03-24 IST"
format(a, format="the time is %Y-%m-%d %H:%M:%S")
# [1] "the time is 2017-03-24 00:00:00" "the time is 2017-03-24 00:00:00"

  
      
  1. 为什么在指定格式后无法转换第一个字符串?
  2.   

正如@ Dave2e所说,根据夏令时转换,该时间“从未发生”。

根据https://www.timeanddate.com/time/change/israel/jerusalem?year=2017

  

2017年3月24日-夏令时开始

     

即将达到当地标准时间   2017年3月24日,星期五,凌晨2:00:00,时钟向前调整了1个小时,   2017年3月24日,星期五,当地夏令时间上午3:00:00。

我将其解释为时钟从01:59:59切换到03:00:00,因此02:**:**从未发生。 R用NA告诉您该时间不应该发生。当然,您可以推断这种方式(破解):找到所有NA值,然后尝试使用一个小时或一个小时或更短的时间进行重新转换;如果新值不是NA,那么您发现另一个实例,其中R认为该时间是不可能的。如果仍然是NA,则字符串中还必须包含其他内容(其他字符,不同顺序等)。

以我的经验,即使逻辑看上去很烦人,我也没有发现这种逻辑是不正确的(尽管我不确定它是否完美无缺)。当我认为这可能是不正确的时,我总是找到其他原因来解释为什么我认为我有这样的精确时间:

  • 数据收集存储了错误的TZ
  • 数据收集无法存储TZ,我推断不正确
  • 管道中的某些转换未正确转换时间和/或区域
  • 可能我还没有扎根的东西