Подтвердить что ты не робот

Получите разницу между датами в виде недель, месяцев, кварталов и лет

У меня есть две даты, давайте скажем 14.01.2013 и 26.03.2014.

Я хотел бы получить разницу между этими двумя датами в виде недель (?), месяцев (в примере 14), кварталов (4) и лет (1).

Вы знаете лучший способ получить это?

4b9b3361

Ответ 1

что об этом:

# get difference between dates `"01.12.2013"` and `"31.12.2013"`

# weeks
difftime(strptime("26.03.2014", format = "%d.%m.%Y"),
strptime("14.01.2013", format = "%d.%m.%Y"),units="weeks")
Time difference of 62.28571 weeks

# months
(as.yearmon(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearmon(strptime("14.01.2013", format = "%d.%m.%Y")))*12
[1] 14

# quarters
(as.yearqtr(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearqtr(strptime("14.01.2013", format = "%d.%m.%Y")))*4
[1] 4

# years
year(strptime("26.03.2014", format = "%d.%m.%Y"))-
year(strptime("14.01.2013", format = "%d.%m.%Y"))
[1] 1

as.yearmon() и as.yearqtr() находятся в пакете zoo. year() находится в пакете lubridate. Как вы думаете?

Ответ 2

Все существующие ответы несовершенны (IMO) и либо делают предположения о желаемом выходе, либо не обеспечивают гибкость для желаемого вывода.

Основываясь на примерах из OP, и OP заявили ожидаемые ответы, я думаю, что это ответы, которые вы ищете (плюс некоторые дополнительные примеры, которые облегчают экстраполяцию).

(Это требует только базы R и не требует зоопарка или lubridate)

Преобразование в объекты Datetime

date_strings = c("14.01.2013", "26.03.2014")
datetimes = strptime(date_strings, format = "%d.%m.%Y") # convert to datetime objects

Разница в днях

Вы можете использовать diff в днях, чтобы получить некоторые из наших более поздних ответов

diff_in_days = difftime(datetimes[2], datetimes[1], units = "days") # days
diff_in_days
#Time difference of 435.9583 days

Разница в неделях

Разница в неделях - частный случай units = "weeks" в difftime()

diff_in_weeks = difftime(datetimes[2], datetimes[1], units = "weeks") # weeks
diff_in_weeks
#Time difference of 62.27976 weeks

Обратите внимание, что это то же самое, что делить наш diff_in_days на 7 (7 дней в неделю)

as.double(diff_in_days)/7
#[1] 62.27976

Разница в годах

С подобной логикой мы можем получить годы от diff_in_days

diff_in_years = as.double(diff_in_days)/365 # absolute years
diff_in_years
#[1] 1.194406

Кажется, вы ожидаете, что разница в годах будет "1", поэтому я предполагаю, что вы просто хотите считать абсолютные календарные годы или что-то еще, что вы можете легко сделать, используя floor()

# get desired output, given your definition of 'years'
floor(diff_in_years)
#[1] 1

Разница в кварталах

# get desired output for quarters, given your definition of 'quarters'
floor(diff_in_years * 4)
#[1] 4

Разница в месяцах

Можно вычислить это как преобразование из diff_years

# months, defined as absolute calendar months (this might be what you want, given your question details)
months_diff = diff_in_years*12
floor(month_diff)
#[1] 14

Я знаю, что этот вопрос старый, но, учитывая, что мне все еще приходилось решать эту проблему только сейчас, я думал, что добавлю свои ответы. Надеюсь, поможет.

Ответ 3

В течение нескольких недель вы можете использовать функцию difftime:

date1 <- strptime("14.01.2013", format="%d.%m.%Y")
date2 <- strptime("26.03.2014", format="%d.%m.%Y")
difftime(date2,date1,units="weeks")
Time difference of 62.28571 weeks

Но difftime не работает с длительностью в течение нескольких недель. Ниже приведено очень субоптимальное решение, использующее cut.POSIXt для этих длительностей, но вы можете обойти его:

seq1 <- seq(date1,date2, by="days")
nlevels(cut(seq1,"months"))
15
nlevels(cut(seq1,"quarters"))
5
nlevels(cut(seq1,"years"))
2

Это, однако, количество месяцев, кварталов или лет, охватываемых вашим временным интервалом, а не продолжительность вашего интервала времени, выраженная в месяцах, кварталах, годах (поскольку у них нет постоянной продолжительности). Учитывая комментарий, сделанный вами в ответ @SvenHohenstein, я думаю, вы можете использовать nlevels(cut(seq1,"months")) - 1 для достижения того, чего вы пытаетесь достичь.

Ответ 4

Я только что написал это для другого вопроса, а затем споткнулся.

library(lubridate)

#' Calculate age
#' 
#' By default, calculates the typical "age in years", with a
#' \code{floor} applied so that you are, e.g., 5 years old from
#' 5th birthday through the day before your 6th birthday. Set
#' \code{floor = FALSE} to return decimal ages, and change \code{units}
#' for units other than years.
#' @param dob date-of-birth, the day to start calculating age.
#' @param age.day the date on which age is to be calculated.
#' @param units unit to measure age in. Defaults to \code{"years"}. Passed to \link{\code{duration}}.
#' @param floor boolean for whether or not to floor the result. Defaults to \code{TRUE}.
#' @return Age in \code{units}. Will be an integer if \code{floor = TRUE}.
#' @examples
#' my.dob <- as.Date('1983-10-20')
#' age(my.dob)
#' age(my.dob, units = "minutes")
#' age(my.dob, floor = FALSE)
age <- function(dob, age.day = today(), units = "years", floor = TRUE) {
    calc.age = interval(dob, age.day) / duration(num = 1, units = units)
    if (floor) return(as.integer(floor(calc.age)))
    return(calc.age)
}

Примеры использования:

my.dob <- as.Date('1983-10-20')

age(my.dob)
# [1] 31

age(my.dob, floor = FALSE)
# [1] 31.15616

age(my.dob, units = "minutes")
# [1] 16375680

age(seq(my.dob, length.out = 6, by = "years"))
# [1] 31 30 29 28 27 26

Ответ 5

Здесь решение:

dates <- c("14.01.2013", "26.03.2014")

# Date format:
dates2 <- strptime(dates, format = "%d.%m.%Y")

dif <- diff(as.numeric(dates2)) # difference in seconds

dif/(60 * 60 * 24 * 7) # weeks
[1] 62.28571
dif/(60 * 60 * 24 * 30) # months
[1] 14.53333
dif/(60 * 60 * 24 * 30 * 3) # quartes
[1] 4.844444
dif/(60 * 60 * 24 * 365) # years
[1] 1.194521

Ответ 6

попробуйте это в течение нескольких месяцев

StartDate <- strptime("14 January 2013", "%d %B %Y") 
EventDates <- strptime(c("26 March 2014"), "%d %B %Y") 
difftime(EventDates, StartDate)