如何解释闰年?

时间:2011-12-13 14:24:09

标签: r date

我对闰年有些怀疑,我如何通过使用这样的公式来确定

add.years= function(x,y){    
if(!isTRUE(all.equal(y,round(y)))) stop("Argument \"y\" must be an integer.\n")
x <- as.POSIXlt(x)
x$year <- x$year+y
as.Date(x)
}

它会考虑闰年,例如在观察数据集中添加100年?我该怎么控制呢?

我有一个50年观察的时间序列数据集:

   date    obs
1995-01-01 1.0
1995-01-02 2.0
1995-01-03 2.5
...
2045-12-30 0.2
2045-12-31 0.1

数据集+ 100年

   date    obs
2095-01-01 1.0
2095-01-02 2.0
2095-01-03 2.5
...
2145-12-30 0.2
2145-12-31 0.1

经过基本检查后,我注意到原始数据集和数据集后100年的行数相同。我不确定在闰年之前的第29届Februray之前是什么,现在是3月1日非闰年的价值等等。

我可以使用 chron库函数 leap.year 检查闰年,但是我想知道是否有更简单的方法来执行此操作,确保将删除在100年后不存在的2月29日通过日期的行,并添加2月29日的新日期和NA值。

4 个答案:

答案 0 :(得分:14)

您可以leap_year检查一年是否为lubridate的闰年。

years <- 1895:2005
years[leap_year(years)]

这个包也将处理2月29日不可能发生的事情。

ymd("2000-2-29") + years(1)    # NA
ymd("2000-2-29") %m+% years(1) # "2001-02-28"

如@VitoshKa所述,%m+%“添加月份”运算符会在实际日期不存在的情况下将日期回滚到上个月的末尾。

答案 1 :(得分:3)

如果出现以下情况,则一年是闰年:

  • 可被4整除。
  • 如果它可以被100整除则不行。
  • 但是如果它可以被400整除。

这就是为什么2000年是闰年的原因(尽管它可以被100整除,它也可以被400整除)。

但一般来说,如果您有一个可以进行日期/时间计算的库,那么请使用它。进行这些计算非常复杂,容易出错,特别是涉及古代日期(日历改革)和时区。

答案 2 :(得分:1)

你的怀疑确实是对的:

x <- as.POSIXlt("2000-02-29")
y <- x
y$year <- y$year+100
y
#[1] "2100-03-01"

奇怪的是y的其他部分保持不变,所以你不能用它们进行比较:

y$mday
#[1] 29
y$mon
#[1] 1

但您可以使用strftime

strftime(x,"%d")
#[1] "29"
strftime(y,"%d")
#[1] "01"

那怎么样:

add.years <- function(x,y){
   if(!isTRUE(all.equal(y,round(y)))) stop("Argument \"y\" must be an integer.\n")
   x.out <- as.POSIXlt(x)
   x.out$year <- x.out$year+y
   ifelse(strftime(x,"%d")==strftime(x.out,"%d"),as.Date(x.out),NA)
   } 

然后,您可以使用[is.na对数据进行子集,以摆脱3月1日的重复日期。虽然这些日期似乎是连续的,但您可能需要考虑使用seq.Date并避免丢弃数据的解决方案。

答案 3 :(得分:0)

按照DarkDustDirk Eddelbuettel的建议,您可以轻松滚动自己的leap_year函数:

leap_year <- function(year) {
  return(ifelse((year %%4 == 0 & year %%100 != 0) | year %%400 == 0, TRUE, FALSE))
}

并将其应用于矢量数据:

years = 2000:2050
years[leap_year(years)]

[1] 2000 2004 2008 2012 2016 2020 2024 2028 2032 2036 2040 2044 2048