% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/date.R
\name{date-count-between}
\alias{date-count-between}
\alias{date_count_between.Date}
\title{Counting: date}
\usage{
\method{date_count_between}{Date}(start, end, precision, ..., n = 1L)
}
\arguments{
\item{start, end}{\verb{[Date]}

A pair of date vectors. These will be recycled to their common
size.}

\item{precision}{\verb{[character(1)]}

One of:
\itemize{
\item \code{"year"}
\item \code{"quarter"}
\item \code{"month"}
\item \code{"week"}
\item \code{"day"}
}}

\item{...}{These dots are for future extensions and must be empty.}

\item{n}{\verb{[positive integer(1)]}

A single positive integer specifying a multiple of \code{precision} to use.}
}
\value{
An integer representing the number of \code{precision} units between
\code{start} and \code{end}.
}
\description{
This is a Date method for the \code{\link[=date_count_between]{date_count_between()}} generic.

\code{date_count_between()} counts the number of \code{precision} units between
\code{start} and \code{end} (i.e., the number of years or months). This count
corresponds to the \emph{whole number} of units, and will never return a
fractional value.

This is suitable for, say, computing the whole number of years or months
between two dates, accounting for the day of the month.

\emph{Calendrical based counting:}

These precisions convert to a year-month-day calendar and count while in that
type.
\itemize{
\item \code{"year"}
\item \code{"quarter"}
\item \code{"month"}
}

\emph{Time point based counting:}

These precisions convert to a time point and count while in that type.
\itemize{
\item \code{"week"}
\item \code{"day"}
}

For dates, whether a calendar or time point is used is not all that
important, but is is fairly important for date-times.
}
\details{
\code{"quarter"} is equivalent to \code{"month"} precision with \code{n} set to \code{n * 3L}.
}
\section{Comparison Direction}{

The computed count has the property that if \code{start <= end}, then
\verb{start + <count> <= end}. Similarly, if \code{start >= end}, then
\verb{start + <count> >= end}. In other words, the comparison direction between
\code{start} and \code{end} will never change after adding the count to \code{start}. This
makes this function useful for repeated count computations at
increasingly fine precisions.
}

\examples{
start <- date_parse("2000-05-05")
end <- date_parse(c("2020-05-04", "2020-05-06"))

# Age in years
date_count_between(start, end, "year")

# Number of "whole" months between these dates. i.e.
# `2000-05-05 -> 2020-04-05` is 239 months
# `2000-05-05 -> 2020-05-05` is 240 months
# Since 2020-05-04 occurs before the 5th of that month,
# it gets a count of 239
date_count_between(start, end, "month")

# Number of "whole" quarters between (same as `"month"` with `n * 3`)
date_count_between(start, end, "quarter")
date_count_between(start, end, "month", n = 3)

# Number of days between
date_count_between(start, end, "day")

# Number of full 3 day periods between these two dates
date_count_between(start, end, "day", n = 3)

# Essentially the truncated value of this
date_count_between(start, end, "day") / 3

# ---------------------------------------------------------------------------

# Breakdown into full years, months, and days between
x <- start

years <- date_count_between(x, end, "year")
x <- add_years(x, years)

months <- date_count_between(x, end, "month")
x <- add_months(x, months)

days <- date_count_between(x, end, "day")
x <- add_days(x, days)

data.frame(
  start = start,
  end = end,
  years = years,
  months = months,
  days = days
)

# Note that when breaking down a date like that, you may need to
# set `invalid` during intermediate calculations
start <- date_build(2019, c(3, 3, 4), c(30, 31, 1))
end <- date_build(2019, 5, 05)

# These are 1 month apart (plus a few days)
months <- date_count_between(start, end, "month")

# But adding that 1 month to `start` results in an invalid date
try(add_months(start, months))

# You can choose various ways to resolve this
start_previous <- add_months(start, months, invalid = "previous")
start_next <- add_months(start, months, invalid = "next")

days_previous <- date_count_between(start_previous, end, "day")
days_next <- date_count_between(start_next, end, "day")

# Resulting in slightly different day values.
# No result is "perfect". Choosing "previous" or "next" both result
# in multiple `start` dates having the same month/day breakdown values.
data.frame(
  start = start,
  end = end,
  months = months,
  days_previous = days_previous,
  days_next = days_next
)
}
