为什么 chron 包从 2030 年开始奇怪地对待两位数的年份?

Why is the chron package treating 2 digit years oddly starting from 2030?

我最近注意到 R 中有一个我无法解释的奇怪行为。我在一些旧代码中有这个:

以下应生成从 01/1980 -> 01/2029 的月份列表,并且按预期工作:

length(chron::seq.dates("01/31/80", "01/03/29", by="months"))
[1] 588

这就是事情变得奇怪的地方。以下内容与上述内容相同,但应生成 2030 年之前的日期:

length(chron::seq.dates("01/31/80", "01/03/30", by="months"))
Error during wrapup: "from" must be a date before "to"

那么这里发生了什么?

最好转换为 Date class,因为当我们延长年份时,两位数的年份可能是个问题。

library(chron)
date1 <- as.Date("01/31/80", format = "%m/%d/%y")
date2 <- as.Date("01/03/30", format = "%m/%d/%y")

这里,转换正确

date1
#[1] "1980-01-31"
date2
#[1] "2030-01-03"

基于 ?seq.dates,我们可以传递 character 字符串或 numeric 值(将 'Date' class 转换为 'numeric'

length(seq.dates(as.numeric(date1), as.numeric(date2), by = "months"))
#[1] 600

julian日期

j1 <- julian(date1, origin = as.Date('1970-01-01'))
j2 <- julian(date2, origin = as.Date('1970-01-01')) 
length(seq.dates(j1, j2, by = 'months'))
#[1] 600

或使用 character 格式的 4 位数年份

length(chron::seq.dates("01/31/1980", "01/03/2030", by="months"))
#[1] 600

如果日期已经有 2 位数字,可以用 sub

插入特定数字
sub("(\d+)$", "20\1", "01/03/30")
#[1] "01/03/2030"

并在 seq.dates

中传递该值
length(seq.dates("01/31/80", sub("(\d+)$", "20\1", "01/03/30"), by = "months"))
#[1] 600

当将两位数年份扩展为四位数年份时,默认情况下 chron 截止值为 30。也就是说,如果两位数年份小于 30,则假定为 20yy,否则为 19yy。这是由 chron.year.expand 选项控制的,该选项默认设置为 chron year.expand 函数,该函数又具有默认截止值 30,但可以按如下方式更改:

library(chron)

# change cutoff to 50
options(chron.year.expand = 
     function (y, cut.off = 50, century = c(1900, 2000), ...) {
        chron:::year.expand(y, cut.off = cut.off, century = century, ...)
     }
)

length(seq.dates("01/31/80", "01/03/30", by="months"))
## [1] 600

这些中的每一个都可以工作,并且不需要设置 chron.year.expand

length(seq(as.chron("1980-01-31"), as.chron("2030-01-03"), by="months"))

length(seq.dates("01/31/80", as.chron("2030-01-03"), by="months"))

length(seq.dates("01/31/80", chron(julian(1, 3, 2030)), by="months"))

length(seq.dates("01/31/80", julian(1, 3, 2030), by="months"))

length(as.chron(seq(as.Date("1980-01-31"), as.Date("2030-01-03"), by = "month")))

length(seq.dates("01/31/80", length = 600, by="months"))

在 Linux Mint 上使用 R4.1 运行ning,下面的代码显示了我所看到的。默认截止值似乎是 68,而不是 30。有没有办法在给定的 R 安装中将真正的默认截止值指定为 30?换句话说,我不想每次 运行 R.

时都必须 运行 上面给出的选项函数将其设置为 30

library(chron)

chron("2/29/68")-chron("11/23/69") Time in days: [1] 35892

chron("2/29/1968")-chron("11/23/1969") [1] -633

options(chron.year.expand =

  • function (y, cut.off = 30, century = c(1900, 2000), ...) {
    
  • chron:::year.expand(y, cut.off = cut.off, century = century, ...)
    
  • }
    
  • )

chron("2/29/68")-chron("11/23/69") [1] -633

chron("2/29/1968")-chron("11/23/1969") [1] -633