简体   繁体   English

两个日期之间的月数

[英]Number of months between two dates

Is there a standard/common method/formula to calculate the number of months between two dates in R?是否有标准/通用方法/公式来计算 R 中两个日期之间的月数?

I am looking for something that is similar to MathWorks months function我正在寻找类似于MathWorks 月函数的东西

I was about to say that's simple, but difftime() stops at weeks.我正要说这很简单,但difftime()在几周内停止。 How odd.多么奇怪。

So one possible answer would be to hack something up:所以一个可能的答案是破解一些东西:

# turn a date into a 'monthnumber' relative to an origin
R> monnb <- function(d) { lt <- as.POSIXlt(as.Date(d, origin="1900-01-01")); \
                          lt$year*12 + lt$mon } 
# compute a month difference as a difference between two monnb's
R> mondf <- function(d1, d2) { monnb(d2) - monnb(d1) }
# take it for a spin
R> mondf(as.Date("2008-01-01"), Sys.Date())
[1] 24
R> 

Seems about right.似乎是对的。 One could wrap this into some simple class structure.可以将其包装成一些简单的类结构。 Or leave it as a hack :)或者把它作为一个黑客:)

Edit: Also seems to work with your examples from the Mathworks:编辑:似乎也适用于 Mathworks 中的示例:

R> mondf("2000-05-31", "2000-06-30")
[1] 1
R> mondf(c("2002-03-31", "2002-04-30", "2002-05-31"), "2002-06-30")
[1] 3 2 1
R> 

Adding the EndOfMonth flag is left as an exercise to the reader :)添加EndOfMonth标志留给读者作为练习:)

Edit 2: Maybe difftime leaves it out as there is no reliable way to express fractional difference which would be consistent with the difftime behavior for other units.编辑 2:也许difftime将其排除在外,因为没有可靠的方法来表达与其他单位的difftime行为一致的分数差异。

A simple function...一个简单的函数...

elapsed_months <- function(end_date, start_date) {
    ed <- as.POSIXlt(end_date)
    sd <- as.POSIXlt(start_date)
    12 * (ed$year - sd$year) + (ed$mon - sd$mon)
}

Example...例子...

>Sys.time()
[1] "2014-10-29 15:45:44 CDT"
>elapsed_months(Sys.time(), as.Date("2012-07-15"))
[1] 27
>elapsed_months("2002-06-30", c("2002-03-31", "2002-04-30", "2002-05-31"))
[1] 3 2 1

To me it makes sense to think about this problem as simply subtracting two dates, and since minuend − subtrahend = difference (wikipedia) , I put the later date first in the parameter list.对我来说,将这个问题简单地视为减去两个日期是有意义的,并且由于minuend − subtrahend = difference (wikipedia) ,我将较晚的日期放在参数列表中。

Note that it works fine for dates preceeding 1900 despite those dates having internal representations of year as negative, thanks to the rules for subtracting negative numbers...请注意,它适用于 1900 年之前的日期,尽管这些日期的内部表示年份为负数,这要归功于减去负数的规则......

> elapsed_months("1791-01-10", "1776-07-01")
[1] 174

I think this is a closer answer to the question asked in terms of parity with MathWorks function我认为这是对在与 MathWorks 函数的奇偶校验方面提出的问题的更接近答案

MathWorks months function MathWorks 月函数

MyMonths = months(StartDate, EndDate, EndMonthFlag)

My R code我的 R 代码

library(lubridate)
interval(mdy(10012015), today()) %/% months(1)

Output (as when the code was run in April 2016)输出(如代码在 2016 年 4 月运行时)

[1] 6

Lubridate [package] provides tools that make it easier to parse and manipulate dates. Lubridate [package]提供的工具可以更轻松地解析和操作日期。 These tools are grouped below by common purpose.这些工具按共同用途分组如下。 More information about each function can be found in its help documentation.有关每个功能的更多信息可以在其帮助文档中找到。

interval {lubridate} creates an Interval-class object with the specified start and end dates. interval {lubridate}创建一个具有指定开始和结束日期的 Interval 类对象。 If the start date occurs before the end date, the interval will be positive.如果开始日期早于结束日期,则间隔将为正。 Otherwise, it will be negative否则为负

today {lubridate} The current date今天 {lubridate}当前日期

months {Base} Extract the month These are generic functions: the methods for the internal date-time classes are documented here.月份{Base}提取月份 这些是通用函数:内部日期时间类的方法记录在此处。

%/% {base} indicates integer division AKA ( x %/% y ) (up to rounding error) %/% {base}表示整数除法 AKA ( x %/% y )(最多舍入误差)

There may be a simpler way.可能有更简单的方法。 It's not a function but it is only one line.它不是一个函数,而是只有一行。

length(seq(from=date1, to=date2, by='month')) - 1

eg例如

> length(seq(from=Sys.Date(), to=as.Date("2020-12-31"), by='month')) - 1

Produces:产生:

[1] 69

This calculates the number of whole months between the two dates.这将计算两个日期之间的整月数。 Remove the -1 if you want to include the current month/ remainder that isn't a whole month.如果要包括当前月份/不是整月的剩余时间,请删除 -1。

There is a message just like yours in the R-Help mailing list (previously I mentioned a CRAN list).在 R-Help 邮件列表中有一条与您类似的消息(之前我提到了 CRAN 列表)。

Here the link .这里的链接 There are two suggested solutions:有两种建议的解决方案:

  • There are an average of 365.25/12 days per month so the following expression gives the number of months between d1 and d2:每月平均有 365.25/12 天,因此以下表达式给出了 d1 和 d2 之间的月数:
 #test data d1 <- as.Date("01 March 1950", "%d %B %Y") d2 <- as.Date(c("01 April 1955", "01 July 1980"), "%d %B %Y") # calculation round((d2 - d1)/(365.25/12))
  • Another possibility is to get the length of seq.Dates like this:另一种可能性是像这样获得seq.Dates的长度:
 as.Date.numeric <- function(x) structure(floor(x+.001), class = "Date") sapply(d2, function(d2) length(seq(d1, as.Date(d2), by = "month")))-1
library(lubridate)

case1: naive function案例1:朴素函数

mos<-function (begin, end) {
      mos1<-as.period(interval(ymd(begin),ymd(end)))
      mos<-mos1@year*12+mos1@month
      mos
}

case2: if you need to consider only 'Month' regardless of 'Day'案例2:如果您只需要考虑“月”而不考虑“日”

mob<-function (begin, end) {
      begin<-paste(substr(begin,1,6),"01",sep="")
      end<-paste(substr(end,1,6),"01",sep="")
      mob1<-as.period(interval(ymd(begin),ymd(end)))
      mob<-mob1@year*12+mob1@month
      mob
}

Example :例子 :

mos(20150101,20150228) # 1
mos(20150131,20150228) # 0
# you can use "20150101" instead of 20150101

mob(20150131,20150228) # 1
mob(20150131,20150228) # 1
# you can use a format of "20150101", 20150101, 201501
library(lubridate)
date1 = "1 April 1977"
date2 = "7 July 2017"

date1 = dmy(date1)
date2 = dmy(date2)
number_of_months = (year(date1) - year(date2)) * 12 + month(date1) - month(date2)

Difference in months = 12 * difference in years + difference in months.月差 = 12 * 年差 + 月差。

Following may need to be corrected using ifelse condition for the month subtractions以下可能需要使用ifelse条件进行月份减法校正

For me this is what worked:对我来说,这是有效的:

library(lubridate)

Pagos$Datediff <- (interval((Pagos$Inicio_FechaAlta), (Pagos$Inicio_CobFecha)) %/% months(1))

The output is the number of months between two dates and stored in a column of the Pagos data frame.输出是两个日期之间的月数,并存储在 Pagos 数据框的一列中。

You can use as.yearmon() function from zoo package.您可以使用 zoo 包中的 as.yearmon() 函数。 This function converts a Date type variable to a year-month type variable.此函数将日期类型变量转换为年月类型变量。 You can subtract two year-month type variables and then multiple by 12 to get diff in months as follows:您可以减去两个 year-month 类型变量,然后乘以 12 以得到月差异,如下所示:

12 * (as.yearmon(Date1) - as.yearmon(Date2))

Date difference in months以月为单位的日期差异

$date1 = '2017-01-20';
$date2 = '2019-01-20';

$ts1 = strtotime($date1);
$ts2 = strtotime($date2);

$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);

$month1 = date('m', $ts1);
$month2 = date('m', $ts2);

echo $joining_months = (($year2 - $year1) * 12) + ($month2 - $month1);

Another short and convenient way is this:另一种简短方便的方法是:

day1 <- as.Date('1991/04/12')
day2 <- as.Date('2019/06/10')
round(as.numeric(day2 - day1)/30.42)

[1] 338 [1] 338

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM