比较 POSIXlt 对象和日期字符串是不是正确?

Posted

技术标签:

【中文标题】比较 POSIXlt 对象和日期字符串是不是正确?【英文标题】:Comparing POSIXlt object with date string the right thing?比较 POSIXlt 对象和日期字符串是否正确? 【发布时间】:2014-11-02 02:48:11 【问题描述】:

我最近遇到了将 POSIXlt 日期对象与日期字符串进行比较的 R 代码。

as.POSIXlt.date("2007-02-02") >= "2007-02-01"
[1] FALSE

结果,至少对我来说令人惊讶的是,结果是 FALSE。我期待 POSIXlt 对象将被强制转换为字符向量,因此不等式应该测试为 TRUE。然后我尝试了显式强制,并将任何一方强制转换为另一方的类型,结果为真。

as.character(as.POSIXlt.date("2007-02-02")) >= "2007-02-01"
[1] TRUE

as.POSIXlt.date("2007-02-02") >= as.POSIXlt.date("2007-02-01")
[1] TRUE

我认为将 LHS 日期对象强制为字符向量在语义上是错误的,因为比较将是字典顺序的,这不是预期的(尽管在这种情况下它的计算结果为 TRUE)。我说的对吗?

在我看来,第三个表达式是语义正确的代码。但是为什么第一个代码不起作用(它评估为 FALSE)?在比较之前,R 不是将双方强制转换为字符向量吗?

这是我的平台信息:

R version 3.1.0 (2014-04-10) -- "Spring Dance"
Platform: x86_64-redhat-linux-gnu (64-bit)

我是 R 新手。非常感谢任何帮助。

谢谢, 法尔汉

【问题讨论】:

我以为我明白了原因,但是在查看了代码之后,我现在感到困惑。看来这两个参数都应该被强制转换为 POSIXct 但不是。认为Ops.POSIXt 会被调用,但现在认为由于比较运算符是原始的,所以没有进行类检查。 您运行的是什么版本的 R?当我将as.POSIXlt.date("2007-02-02") >= "2007-02-01" 复制/粘贴到我的R 会话中时,我得到TRUE(版本3.1.1)。 @BondedDust 至少对我来说,如果我这样做 debugonce(Ops.POSIXt) 我可以看到正在调用该函数。 OP,as.POSIXlt.date("2007-02-02") == as.POSIXct("2007-02-02") 是否会为您返回 TRUE?你的Sys.timezone() 是什么? 我仍在使用 R 3.1.0(已修补)。我查看了 NEWS 文件,并没有看到这在哪里被特别报告为错误或修复。我正在使用 trace() 并没有看到 Ops.POSIXt 被调用,但确实看到它与 debugonce 一起出现。现在我想知道在对“e2”进行操作之前,我在条件中看到的as.character(e1) 的第二个实例是否更改为as.character(e2),但未记录在NEWS 文件中。 所以答案似乎是......不,比较不是作为一个字符,而是作为一个数字......在两者都被 as.POSIXct 强制之后......但只有在最新版本的 R 中。我可以确认更新到 3.1.1 给出了预期的答案:> as.POSIXlt.date("2007-02-02") >= "2007-02-01" # [1] TRUE 感谢@BondedDust 我正在使用 R 3.1.0。有没有关于这种转换为 POSIXct 的文档?除了帮助页面中宝贵的几行之外,我一般找不到太多关于强制的信息。我在这里引用它们。 “如果两个参数是不同类型的原子向量,一个被强制转换为另一个的类型,优先级(递减)顺序是字符,复杂,数字,......”和“'x'和'y' 必须是原子向量,但如果另一个是列表,R 会尝试将其强制转换为原子向量的类型”。 【参考方案1】:

一般来说,比较时日期应该都是class日期

它在某些情况下有效,因为 R 在幕后将字符串 "2007-02-01" 转换为 Date,这在某些情况下可能会失败:

as.Date("2020-09-12") <= "2020:09:13"
# Error in charToDate(x) : 
#   character string is not in a standard unambiguous format

另外,请注意不兼容的不同 Date 方法:

as.POSIXlt("2007-02-02") <= as.Date("2020,01,12", "%Y,%m,%d")
#   sec    min   hour   mday    mon   year   wday   yday  isdst   zone gmtoff 
#  TRUE   TRUE   TRUE   TRUE   TRUE   TRUE   TRUE   TRUE   TRUE     NA     NA 
#Warning messages:
#1: Incompatible methods ("Ops.POSIXt", "Ops.Date") for "<=" 
#2: NAs introduced by coercion 

顺便说一句,我无法再重现第一个示例(R 版本 4.0.3):

as.POSIXlt.date("2007-02-02") >= "2007-02-01"
# Error in as.POSIXlt.date("2007-02-02") : 
#   could not find function "as.POSIXlt.date"

as.POSIXlt.Date("2007-02-02") >= "2007-02-01"
# [1] NA
# Warning message:
# In as.POSIXlt.Date("2007-02-02") : NAs introduced by coercion

【讨论】:

以上是关于比较 POSIXlt 对象和日期字符串是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章

R在POSIXlt日期序列中标记多个日期期间

苹果健康时间序列 as.xts as.POSIXlt.character(x, tz, ...) 中的错误:字符串不是标准的明确格式 [关闭]

java中怎么做到判断输入的日期是不是合法

R语言--数据预处理

日期对象 SimpleDateFormat 未在 Java(Android)环境中正确解析时间戳字符串

日期对象的正确写法