【问题标题】:Calculate time difference on only months and days仅计算月份和日期的时差
【发布时间】:2019-05-17 03:00:28
【问题描述】:

我想只考虑天数和月份来计算时差。 例如:

> as.Date("2018-12-15")-as.Date("2018-12-16")
Time difference of -1 days

> as.Date("2008-12-15")-as.Date("2018-12-16")
Time difference of -3653 days

我希望它们都返回 -1。

编辑: 不应考虑闰年,因为我们只需要一个近似值,返回值不需要精确。

【问题讨论】:

  • 我建议在新列中人为地将所有年份设置为相同的年份
  • @OmryAtia 这实际上可行,将尝试。谢谢

标签: r datetime


【解决方案1】:

正如@Omry Atia 所建议的,我们可以将年份组件设置为同一年,然后计算差异。

library(lubridate)

get_difference_without_years <- function(x, y) {
    x <- ymd(x)
    year(x) <- 2018
    y <- ymd(y)
    year(y) <- 2018
    x - y
}


get_difference_without_years("2018-12-15", "2018-12-16")
#Time difference of -1 days

get_difference_without_years("2008-12-15", "2018-12-16")
#Time difference of -1 days

将其保存在基础 R

get_difference_without_years <- function(x, y) {
  x <- as.Date(paste0("2018-", format(as.Date(x), "%m-%d")))
  y <- as.Date(paste0("2018-", format(as.Date(y), "%m-%d")))
  x - y
}

get_difference_without_years("2008-12-15", "2018-12-16")
#Time difference of -1 days
get_difference_without_years("2018-12-15", "2018-12-16")
#Time difference of -1 days

【讨论】:

    【解决方案2】:

    对于日期跨越 2 月底并且一年是闰年并且不是闰年的情况,这个问题没有得到很好的定义,但如果忽略这一点,我们可以将每个日期中的年份替换为闰年,如果其中一个是闰年闰年(2000 年)和非闰年(1999 年),否则减去:

    library(lubridate)
    
    d1 <- "2008-12-15"
    d2 <- "2018-12-16"
    
    yr <- 1999 + (leap_year(as.Date(d1)) || leap_year(as.Date(d2)))
    as.Date(sub("....", yr, d1)) - as.Date(sub("....", yr, d2))
    ## Time difference of -1 days
    

    添加

    发帖人在评论中表示我们可以忽略闰年带来的问题。在这种情况下,我们可以选择闰年作为替代日期,以便它始终返回答案。我们在下面这样做。我们不再需要 lubridate 来检查日期是否为闰年。

    as.Date(sub("....", 2000, d1)) - as.Date(sub("....", 2000, d2))
    ## Time difference of -1 days
    

    (或者,我们可以选择不是闰年的年份,因为大多数年份都不是闰年,因此跨期日期更可能不会放假一天;但是,如果其中一个年份出现,则以失败为代价日期是 2 月 29 日。)

    【讨论】:

    • 是的,更新了新信息。同样在这种特定情况下,闰年并不重要。
    【解决方案3】:

    如果允许我们更近似一些,忽略闰年,我们可以通过在format() 中使用%j(一年中的一天)来简化一些事情。

    yd_diff <- function(x, y=NULL) {
        x <- as.integer(format(x, "%j"))
        if (is.null(y)) {
            diff(x)
        } else {
            x - as.integer(format(y, "%j"))
        }
    }
    
    d1 <- as.Date("2008-12-15")
    d2 <- as.Date("2018-12-16")
    yd_diff(d1, d2)
    # 0
    
    set.seed(1)
    rd <- as.Date(sample(1:10000, 5), origin="1970-01-01")
    yd_diff(rd)
    # -30  180   65 -123
    

    更简单的是,我们可以将日期转换为整数并取一年中的模数。非常好,R 允许您对非整数使用模数。

    (as.integer(d1) %% 365.24) - (as.integer(d2) %% 365.24)
    # -0.6
    
    diff(as.integer(rd) %% 365.24)
    # -30.72  180.80   64.84 -123.44
    

    【讨论】:

      【解决方案4】:

      另一种解决方案可能是仅从每个日期中提取日期,然后进行数学运算,尤其是在闰年很重要的情况下。

      例如,以下内容的 DoY:

      DayOfYear(2020, 12, 15) = 350   # leap year
      DayOfYear(2018, 12, 15) = 349
      DayOfYear(2016, 12, 15) = 350   # leap year
      DayOfYear(2011, 12, 16) = 350
      

      您可以从extract day number of year from datesHow do you convert POSIX date to day of year in R? 找到很多关于如何获得 DoY 的建议。

      【讨论】:

        猜你喜欢
        • 2021-05-17
        • 2021-08-19
        • 2021-02-12
        • 2019-12-27
        • 2013-04-01
        • 1970-01-01
        • 2015-06-20
        • 2018-04-24
        • 1970-01-01
        相关资源
        最近更新 更多