持续时间 {lubridate}:持续时间可以是负数吗?

4

我所阅读的所有文档都表明,lubridate 1.7.4 中的持续时间可以是负数,包括 R 文档中提供的示例:

> duration(-1, "days")
> duration(day = -1)

2009年的一个修复bug的例子与此类似,它提供了示例输出:

> new_duration(secs = -1, mins = -1, hours = -1)
[1] "-1 hours, -1 minutes and -1 seconds"

但是当我运行duration(-1, "days")时,R会返回:
[1] "86400s (~1 days)"

这是怎么回事?


一个持续时间怎么可能是负数?这在逻辑上根本讲不通。 - thc
@thc 任何时候,只要表达式 a - b 有意义,负值的 b 也必然有意义。lubridate 允许从时间中减去持续时间,因此允许这些持续时间为负,并支持否定操作是有意义的。 - Ken Williams
2个回答

6
是的,它们可以是负数。从源代码的阅读中可以看出,这是 Duration 类的打印方法的一个副产品。检查对象显示它仍然保持负数,尽管不显示为负数,并像负数一样运作,如下所示。
我认为罪魁祸首是此处的源代码第102行。当打印 Duration 时,format.Duration 函数会调用 abs。我猜这是有意为之的行为,尽管您需要与开发人员联系以了解原因(可能是因为人们倾向于将持续时间理解为正数)。
编辑:在2019年12月,打印方法已更改为使用前导 - 显示负持续时间,因此现在只会在旧版本的 lubridate 上发生。
library(lubridate)
neg <- duration(-1)
pos <- duration(2)
neg + pos
#> [1] "1s"
unclass(neg)
#> [1] -1

1

我想当你打印它时还有问题,但当时间为负数时持续时间可以正常工作:

date <- mdy("7/8/17")
date - duration(10, "days")
# [1] "2017-06-28"
date + duration(-10, "days)
# [1] "2017-06-28"

持续时间是一个类,其中包含了名为.Data的插槽,该插槽包含以秒为单位的持续时间,并且您可以检查以确认它确实为负数:
duration(-10, "days")@.Data
# [1] -864000
duration(-10, "days")@.Data / 3600 / 24 # to get the days:
# [1] -10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接