【问题标题】:In R, is the %OSn time format only valid for formatting, but not parsing?在 R 中,%OSn 时间格式是否仅对格式化有效,但对解析无效?
【发布时间】:2015-09-09 10:54:08
【问题描述】:

考虑这个 R 代码,它使用定义的时间格式字符串(下面的 timeFormat 变量)来格式化和解析日期:


time = as.POSIXct(1433867059, origin = "1970-01-01")
print(time)
print( as.numeric(time) )

timeFormat = "%Y-%m-%d %H:%M:%OS3"
tz = "EST"

timestamp = format(time, format = timeFormat, tz = tz)
print(timestamp)

timeParsed = as.POSIXct(timestamp, format = timeFormat, tz = tz)
print(timeParsed)
print( as.numeric(timeParsed) )

如果我将其粘贴到运行最新 (3.2.0) 稳定版本的 Windows 机器上的 Rgui 中,我会得到:


> time = as.POSIXct(1433867059, origin = "1970-01-01")
> print(time)
[1] "2015-06-09 12:24:19 EDT"
> print( as.numeric(time) )
[1] 1433867059
> 
> timeFormat = "%Y-%m-%d %H:%M:%OS3"
> tz = "EST"
> 
> timestamp = format(time, format = timeFormat, tz = tz)
> print(timestamp)
[1] "2015-06-09 11:24:19.000"
> 
> timeParsed = as.POSIXct(timestamp, format = timeFormat, tz = tz)
> print(timeParsed)
[1] NA
> print( as.numeric(timeParsed) )
[1] NA

注意以 %OS3 结尾的时间格式如何生成正确的时间戳(3 位数毫秒分辨率)。

但是,相同的时间格式无法将该时间戳解析回原始 POSIXct 值;它会吐出并解析 NA。

有人知道怎么回事吗?

网络搜索发现this stackoverflow link, 其中一位评论者 Waldir Leoncio 在第一个答案中似乎描述了与我所做的 %OS3 相同的解析错误:

"例如使用 strptime(y, "%d.%m.%Y %H:%M:%OS3"),但它没有 为我工作。 Henrik 注意到该函数的帮助页面 ?strptime 指出 %OS3 位是依赖于操作系统的。我正在使用更新的 Ubuntu 13.04 和使用 %OS3 会产生 NA。"

上面引用中提到的帮助页面可能是this link, 不幸的是,这很简洁,只是说

"特定于 R 的是 %OSn,它对于输出给出截断的秒数 到 0

关于 strptime(即解析)的最后一句话很微妙:它说“for strptime %OS”。请注意没有“n”:它说 %OS 而不是 %OSn。

这是否意味着 %OSn 不能用于解析,只能用于格式化?

这是我凭经验发现的,但这是预期的行为还是错误?

非常烦人的行为,因为这意味着我需要不同的时间格式来格式化和解析。以前从未在任何其他语言的日期 API 中看到过这种情况...

(旁白:我知道还有另一个问题,即使您只是想格式化,使用 %OSn:R 会截断小数部分而不是圆形。对于那些不知道这种不良行为的人,讨论了它的危害@987654323 @、herehere。)

【问题讨论】:

  • R-3.2.1,而不是 3.2.0,是截至 2015 年 6 月 18 日的当前稳定版本。截断而不是舍入小数秒的“坏”行为是主观的。我敢肯定,如果选择了其他约定,您会发现很多人抱怨 “不良”行为。

标签: r parsing format posixct


【解决方案1】:

这是预期行为,而不是错误。 "%OSn" 用于输出。 "%OS" 用于输入,包括小数秒,正如它在您的第二个块引用中所说:

此外,strptime %OS 将输入秒数,包括小数秒数。

options(digits.secs=6)
as.POSIXct("2015-06-09 11:24:19.002", "America/New_York", "%Y-%m-%d %H:%M:%OS")
# [1] "2015-06-09 11:24:19.002 EDT"

另请注意,"EST" 是一个不明确的时区,可能不是您所期望的。请参阅?timezone时区名称部分。

【讨论】:

  • 感谢您的回复——以及关于 EST 的好消息(我应该一直使用 EST5EDT)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
相关资源
最近更新 更多