| Title: | Exact Date and Duration Arithmetic on an Annual Grid |
| Version: | 0.1.0 |
| Description: | Standardised mapping of dates onto a discrete annual grid, together with exact date and duration arithmetic. This matters when the primary unit is years but the input data uses dates. Examples are actuarial mortality experience analysis and valuation of life assurance and annuities, for which mortality rates are defined per year but experience and valuation data are typically defined using dates. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/logmu-org/r-datey, https://r-datey.logmu.org/ |
| BugReports: | https://github.com/logmu-org/r-datey/issues |
| Depends: | R (≥ 4.0.0) |
| Suggests: | knitr, pillar, rmarkdown, testthat (≥ 3.0.0) |
| LinkingTo: | cpp11 |
| VignetteBuilder: | knitr |
| Config/roxygen2/markdown: | TRUE |
| Config/roxygen2/version: | 8.0.0 |
| Config/testthat/edition: | 3 |
| Encoding: | UTF-8 |
| Language: | en-GB |
| NeedsCompilation: | yes |
| Packaged: | 2026-07-01 10:40:08 UTC; Tim Gordon |
| Author: | Tim Gordon |
| Maintainer: | Tim Gordon <tim.gordon@btinternet.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-07-07 09:30:15 UTC |
Exact date and duration arithmetic on an annual grid
Description
The datey package provides three types for date and duration arithmetic on an annual grid:
-
datey — a point in time, expressed as a calendar date with an optional day fraction.
-
durationy — a duration in years.
-
datey_interval — a closed-open interval [
start,end) of time.
Arithmetic, comparison and summary operations are defined in ops, mean.datey and max_min.
Author(s)
Maintainer: Tim Gordon tim.gordon@btinternet.com (ORCID)
Authors:
Tim Gordon tim.gordon@btinternet.com (ORCID)
See Also
-
datey, durationy, datey_interval for the core types.
-
ops for arithmetic and comparison operators.
-
vignette("datey")for a worked introduction. -
vignette("why-datey")for the motivation and design of the annual grid.
The datey, durationy and datey_interval versions of NA
Description
Throughout the datey package, NA will cause an error when used where
a datey_, durationy_ or datey_interval_ is expected.
This is because its type is logical and potentially indicates user
error. If you want an NA value with a datey system type, use one of NA_datey_, NA_durationy_
or NA_datey_interval_.
Usage
NA_datey_
NA_datey_interval_
NA_durationy_
Value
Each is a scalar holding the missing-value (NA)
representation of its type: NA_datey_ is a datey, NA_durationy_ is a
durationy and NA_datey_interval_ is a datey_interval.
See Also
is_NA, integer_constants, datey, durationy, datey_interval
Examples
is_datey(NA_datey_)
is.na(NA_datey_)
is_durationy(NA_durationy_)
is.na(NA_durationy_)
is_datey_interval(NA_datey_interval_)
'All of time' — the maximum valid datey_interval
Description
all_of_time is the datey_interval [1000-01-01.0, 3000-01-01.0),
spanning the full valid date range. It is referred to as 'all of time'
throughout the datey documentation.
It is the value produced by datey_interval(TRUE) and is used
when a datey_interval is intersected with a logical TRUE via &.
Usage
all_of_time
Value
A scalar datey_interval spanning the full valid date range,
[1000-01-01.0, 3000-01-01.0).
See Also
Examples
all_of_time
Convert a datey to calendar years (including fractional part)
Description
Converts a datey to calendar years,
including a fractional part that represents the
proportion of the calendar year that has elapsed.
For example, the middle of 2000-10-01 is precisely three-quarters through
the (leap) year 2000 and so as.double(mid_day(2000,10,1)) results in
2000.75.
as.numeric() is the same as as.double().
as.integer() gives the calendar year as an integer, e.g.
as.integer(datey(2000.75)) is 2000.
It is also the case that if x is a datey then
as.integer(x) is the same as as.integer(as.double(x)).
Usage
## S3 method for class 'datey'
as.double(x, ...)
## S3 method for class 'datey'
as.integer(x, ...)
Arguments
x |
The |
... |
Not used. |
Value
A vector of double.
See Also
datey, as_years_durationy, ops
Examples
t <- datey(2000.75)
t # 2000-10-01.5
as.double(t) # 2000.75
as.numeric(t) # 2000.75
as.integer(t) # 2000
identical(as.integer(t), 2000L) # TRUE
Convert a durationy to duration in years
Description
Converts a durationy to its duration measured in years.
as.numeric() is the same as as.double().
as.integer() obtains the integer part as an integer, e.g.
as.integer(durationy(1.75)) is 1
and as.integer(durationy(-1.75)) is -1 (i.e. rounding towards 0).
It is also the case that if x is a durationy then
as.integer(x) is the same as as.integer(as.double(x)).
Usage
## S3 method for class 'durationy'
as.double(x, ...)
## S3 method for class 'durationy'
as.integer(x, ...)
Arguments
x |
The |
... |
Not used. |
Value
A vector of double.
See Also
durationy, as_years_datey, ops
Examples
d <- durationy(1.75)
d # 1.75 yr
as.double(d) # 1.75
as.numeric(d) # 1.75
as.integer(d) # 1
as.integer(-d) # -1
identical(as.integer(d), 1L) # TRUE
Combine multiple datey, durationy or datey_interval vectors
Description
Combines (flattens) datey, durationy or datey_interval into a single
vector.
All arguments must have the same class, i.e. all dateys, all durationys
or all datey_intervals.
If the first element in c(...) is not a datey, durationy or
datey_interval then this method will not be called. For instance,
c(NA, datey("2000-01-01.0")) results in c(NA_integer_, 1068720000L).
Usage
## S3 method for class 'datey'
c(..., recursive = FALSE)
## S3 method for class 'durationy'
c(..., recursive = FALSE)
## S3 method for class 'datey_interval'
c(..., recursive = FALSE)
Arguments
... |
The items to combine. |
recursive |
Unused. |
Value
c() returns a datey, durationy or datey_interval depending on the
first argument.
See Also
datey, durationy, datey_interval, subset
Examples
c(datey(2000:2019), datey("2020-01-01.0"))
Create a datey
Description
To create a datey use one of the following:
-
start_day()andend_day()are the points in time at the start and end of the day respectively. -
mid_day()is the the middle of the day, commonly used to represent a point in time during the day. -
datey()is the underlying S3 generic function.start_day(),mid_day()andend_day()call through todateywith an explicitday_fractionor0,0.5and1respectively.
The generic types are as follows:
-
doubleandinteger. These are interpreted as calendar year, optionally with a fractional part in the case ofdouble.Valid years are from 1000 to 3000 (although the only legal date in 3000 is the start of 3000-01-01).
Either
(a)
monthandday(and fordatey(),day_fraction) parameters are all provided, in which casexmust be integral, or(b) none of those parameters are provided, in which case
xis interpreted as a fractional calendar year and rounded to the nearest 1 / 534 360 of a year (Banker's rounding). This unit is called a click and is the resolution of all datey arithmetic. For instance,datey(2000.5)means halfway through the year 2000. -
Date. This base R date type is interpreted strictly. (It is possible to end up with an unintentionally fractional underlying value, e.g. by taking a mean ofDates.) Aday_fractionargument is always required. -
POSIXctandPOSIXlt. How these base R date-time types are interpreted depends on whether aday_fractionis provided.If
day_fractionis provided then these are interpreted strictly using the date component only – the time component is ignored completely.If
day_fractionis not provided then the day fraction is determined using the hours, minutes, and seconds. For instance,datey(as.POSIXct("2000-03-21 12:00"))means the middle of 2000-03-21. -
character. How text is parsed depends on whether aday_fractionis provided.If
day_fractionis provided then the text must be in ISO 8601 extended format, i.e.YYYY-MM-DD.If
day_fractionis not provided then the text must be formatted asYYYY-MM-DD[.F..]., where[.F...]is the optional day fraction. This means that e.g."2000-01-01"represents the start of 1 January 2000.If
blank_is_NAisTRUEthen blanks are treated asNA(regardless ofstrict). -
datey. This is interpreted as is but with the optionalday_fractionoverride. Note that aday_fractionof 1 will add a day to a day boundary, even if it was originally defined as an end day.
The lengths of vector arguments must be multiples of each other.
Beware that end_day() will add a day to a datey that is already on a
day boundary, even if it was originally defined as an end day.
There is no is_end_day() predicate: end days are stored identically to
the start of the following day, so is_start_day() is the correct test.
NA arguments of the appropriate type result in NA_datey_
– they do not stop execution (regardless of strict).
Note that NA is logical and therefore it will cause an error.
Usage
datey(x, ...)
## Default S3 method:
datey(x, ...)
## S3 method for class 'datey'
datey(x, day_fraction = NULL, strict = TRUE, ...)
## S3 method for class 'integer'
datey(x, month = NULL, day = NULL, day_fraction = NULL, strict = TRUE, ...)
## S3 method for class 'double'
datey(x, month = NULL, day = NULL, day_fraction = NULL, strict = TRUE, ...)
## S3 method for class 'Date'
datey(x, day_fraction, strict = TRUE, ...)
## S3 method for class 'POSIXct'
datey(x, day_fraction = NULL, strict = TRUE, ...)
## S3 method for class 'POSIXlt'
datey(x, day_fraction = NULL, strict = TRUE, ...)
## S3 method for class 'character'
datey(x, day_fraction = NULL, strict = TRUE, blank_is_NA = FALSE, ...)
start_day(x, month = NULL, day = NULL, strict = TRUE, blank_is_NA = FALSE)
mid_day(x, month = NULL, day = NULL, strict = TRUE, blank_is_NA = FALSE)
end_day(x, month = NULL, day = NULL, strict = TRUE, blank_is_NA = FALSE)
Arguments
x |
The argument to convert to a |
... |
Not used. |
day_fraction |
The If If |
strict |
How non-compliant non-NA inputs should be handled.
If |
month, day |
The month (1–12) and day (1–31).
Valid only for for numeric |
blank_is_NA |
Whether "" should be treated as |
Value
A vector of datey.
See Also
durationy, datey_interval, text_from_datey, as_years_datey,
datey_components, is_xxx_day, is_leap_year, is_NA, ops,
vignette("why-datey", package = "datey") for the annual-grid design,
vignette("datey", package = "datey") for a worked introduction
Examples
start_day(2001, 2, 3)
mid_day(2001, 2, 3)
end_day(2001, 2, 3)
# Must specify month and day for a numeric if day_fraction is provided
# implicitly or explicitly:
try(start_day(2001))
try(mid_day(2001))
try(end_day(2001))
try(datey(2001, day_fraction = 0))
datey(2000) # Start of a year
datey(2000.5) # Middle of a leap year
datey(2001.5) # Middle of a non-leap year
# Convert base R date
r_date <- as.Date("2001-02-03")
c(start_day(r_date), mid_day(r_date), end_day(r_date))
try(datey(r_date)) # Must specify day_fraction for a `Date`
# Convert base R datetime
c_date <- as.POSIXct("2001-02-03 12:00:00") # Midday!
c(start_day(c_date), mid_day(c_date), end_day(c_date))
# An R datetime implies a position within a day:
datey(c_date) # 2001-02-03.5
# Use `strict` to control error behaviour for invalid years:
try(end_day(0999, 12, 31))
try(datey(3000.1))
end_day(0999, 12, 31, strict = FALSE)
datey(3000.1, strict = FALSE)
# NAs are passed through regardless of `strict`
# (provided they are numeric)
end_day(NA_real_, 12, 31, strict = TRUE)
datey(NA_real_, strict = FALSE)
# Text:
start_day("2001-02-03")
mid_day("2001-02-03")
end_day("2001-02-03")
datey("2001-02-03")
datey("2001-02-03.0")
datey("2001-02-03", day_fraction = 0)
datey("2001-02-03.5")
datey("2001-02-03", day_fraction = 0.5)
# Text round trips:
t <- datey(2001.234)
identical(t, datey(as.character(t))) # TRUE
# Day fraction cannot be present
# both in the text and as an argument
# implicitly or explicitly:
try(start_day("2001-02-03.0"))
try(datey("2001-02-03.0", day_fraction = 0))
# Handling blanks:
try(start_day(""))
start_day("", blank_is_NA = TRUE)
# Invalids:
try(mid_day("abc"))
try(mid_day("0999-01-01"))
end_day("abc", strict = FALSE) # NA
end_day("0999-01-01", strict = FALSE) # NA
Get year, month, day or day_fraction breakdown of a datey
Description
To extract the year, month, day or day_fraction breakdown of a datey,
use either
the list-like syntax
$year,$month,$dayor$day_fractiondirect, orif you need several components at once,
to_ymdf(), which returns an actual list ofyear,month,dayandday_fraction.
In this breakdown,
-
yearis anintegerin [1000,3000], -
monthis anintegerin [1,12], -
dayis anintegerin [1,N], where N is the number of days in the month specified byyearandmonth, and -
day_fractionis adoublein [0,1) representing the fraction of the day, where e.g. 0 means the start and 0.5 means the middle of the day.
If the datey was constructed using end_day or day_fraction = 1 then
to_ymdf() will return the start of the next day with day_fraction = 0.
Usage
to_ymdf(x)
## S3 method for class 'datey'
x$name
Arguments
x |
The |
name |
The name of the component for the list-like syntax.
Must be |
Value
to_ymdf() returns a list of
integer vector year,
integer vector month,
integer vector day, and
double vector day_fraction, all with the same length.
The list-like syntax returns these components individually.
See Also
Examples
t <- datey(2001, 2, 3, 0.5)
t
to_ymdf(t)
t$year
t$month
t$day
t$day_fraction
Create a datey_interval
Description
Creates a datey_interval,
a closed-open ('clopen') interval [start, end).
A datey t in included in the interval if start <= t < end.
There are two syntaxes to create a datey_interval from start and end:
operator:
start %to% endfunction:
datey_interval(start, end)
in which start and end are datey or numeric (interpreted as years).
These are equivalent other than strict is always on for the operator
version. The lengths of vector arguments must be multiples of each other.
A datey_interval can also be created from logical, mapping
-
TRUEto [1000,3000), which is referred to as 'all of time' in datey documentation, and -
FALSEandNAtoNA_datey_interval_.
Arguments of the correct type but which are NA
result in NA_datey_interval_
– they do not stop execution (regardless of strict).
Common operations on intervals are
testing for inclusion, i.e. with an interval includes a date –
interval %includes% t, andobtaining the intersection, which uses the
&operator –interval_a & interval b.
Usage
datey_interval(x, ...)
## Default S3 method:
datey_interval(x, ...)
## S3 method for class 'datey_interval'
datey_interval(x, ...)
## S3 method for class 'logical'
datey_interval(x, ...)
## S3 method for class 'datey'
datey_interval(x, end, strict = TRUE, ...)
## S3 method for class 'double'
datey_interval(x, end, strict = TRUE, ...)
## S3 method for class 'integer'
datey_interval(x, end, strict = TRUE, ...)
start %to% end
Arguments
x |
Argument to S3 method |
... |
Not used. |
strict |
How invalid non-NA |
start, end |
The start (inclusive) and end of the interval (exclusive).
These can be any type that is convertible to a |
Value
A vector of datey_interval.
See Also
interval_properties, interval_nature, interval_includes,
all_of_time, durationy, ops, is_NA,
vignette("datey", package = "datey") for a worked introduction
Examples
start <- datey(2000)
end <- datey(2001)
interval <- start %to% end
interval # [2000-01-01.0, 2001-01-01.0)
# Alternative functional syntax:
identical(interval, datey_interval(start, end)) # TRUE
# Can use numeric arguments:
2000 %to% 2001 # [2000-01-01.0, 2001-01-01.0)
# Can use vector arguments:
2000 %to% 2001:2003 # Vector of 3 intervals
# Logical values are mapped to 'all of time' or `NA_datey_interval_`:
datey_interval(c(TRUE, FALSE, NA)) # [1000-01-01.0, 3000-01-01.0) <NA> <NA>
# Test for inclusion in [start, end):
interval %includes% mid_day(1999, 12, 31) # FALSE
interval %includes% start # TRUE -- start *is* included
interval %includes% datey(2000.5) # TRUE
interval %includes% end # FALSE -- end is *not* included
# Obtain the intersection of two intervals
interval2 <- start_day(2000, 12, 1) %to% 2010
interval & interval2 # [2000-12-01.0, 2001-01-01.0)
Create a durationy from an annual duration
Description
durationy() to create a durationy from the following types:
-
integer. The value is interpreted as the specified number of years. -
double. The value is interpreted as the specified number of years, rounded to fixed precision of adurationy. This means thatdurationy(0.5)is precise butdurationy(0.01)is not. -
datey_interval. The duration of the interval provided it is proper (i.e. start <= end). If the interval is improper then the result isNA_durationy_. Whenxis adatey_intervalthenx$durationis identical todurationy(x). (strictis ignored.) -
character. Valid text is of the form[S]...Y[.F...][ U...]where:-
[S]is an optional plus or a minus sign, i.e. one of '+' (U+002B), true minus (U+2212) or ASCII hyphen-minus '-' (U+002D). -
...Yis number of whole years (leading zeros allowed). -
[.F...]is an optional fractional part of year, including '.' to represent the decimal point. -
[ U...]is the unit name for one year preceded by a space if the unit name is not blank. The unit name cannot be longer than 20 UTF-8 bytes or contain control characters.
If
blank_is_NAisTRUEthen blanks are treated asNA. IfstrictisTRUE(the default) then non-compliant text will stop execution. If the text is NA then NA is returned. This is the same format as produced byas.character.durationy(). -
-
durationy. Value is passed through unchanged.
NA arguments of the appropriate type result in NA_durationy_ –
they do not stop execution (regardless of strict).
Note that NA is logical and therefore it will cause an error.
Usage
durationy(x, ...)
## Default S3 method:
durationy(x, ...)
## S3 method for class 'durationy'
durationy(x, ...)
## S3 method for class 'integer'
durationy(x, strict = TRUE, ...)
## S3 method for class 'double'
durationy(x, strict = TRUE, ...)
## S3 method for class 'datey_interval'
durationy(x, ...)
## S3 method for class 'character'
durationy(x, strict = TRUE, blank_is_NA = FALSE, year_unit = "yr", ...)
Arguments
x |
The argument to convert to a |
... |
Not used. |
strict |
How non-compliant non-NA |
blank_is_NA |
Whether blanks should be treated as |
year_unit |
The year unit name to expect.
If not blank then the value is expected to be followed by a space and this unit text.
Cannot be more than 20 characters (UTF-8 bytes) or contain control
characters.
Defaults to |
Value
A vector of durationy.
See Also
datey, datey_interval, text_from_durationy, as_years_durationy,
ops, is_NA,
vignette("why-datey", package = "datey") for the annual-grid design,
vignette("datey", package = "datey") for a worked introduction
Examples
durationy(1) # 1 yr
durationy(0.5) # 0.5 yr
durationy(-2.3) # -2.3 yr
durationy(2001 %to% 2002) # 1 yr
durationy(2002 %to% 2001) # `NA_durationy_` because interval is improper
# NA:
durationy(NA_real_)
try(durationy(NA)) # NA is logical, not numeric
# Invalid durations:
try(durationy(3000.1)) # default strict = TRUE
durationy(3000.1, strict = FALSE)
# Text:
durationy("10 yr")
durationy("+10 yr")
durationy("-10 yr")
durationy("10", year_unit = "")
durationy("10 a", year_unit = "a")
# Text round trips:
d <- durationy(1.234)
identical(d, durationy(as.character(d))) # TRUE
# Handling blank text:
try(durationy(""))
durationy("", blank_is_NA = TRUE)
# Invalid text:
try(durationy("abc"))
try(durationy("2000.000001 yr"))
durationy("abc", strict = FALSE) # NA
durationy("2000.000001 yr", strict = FALSE) # NA
durationy("2000.000000 yr") # This is valid
Integer constants
Description
The following integer constants may make code clearer.
| Constant | Value | Meaning |
valid_years_start | 1000L | The first calendar year for a datey |
valid_years_end | 3000L | The final valid calendar year for a datey (noting that only the start of this year is valid) |
valid_duration_years_max | 2000L | The maximum valid duration in years for a durationy
|
Usage
valid_years_start
valid_years_end
valid_duration_years_max
Value
Each of these constants is a scalar integer giving one
of the boundaries of the valid datey or durationy range described above.
See Also
is_NA, NAs, datey, all_of_time
Examples
datey(valid_years_start - 0.001, strict = FALSE)
datey(valid_years_start)
datey(valid_years_end)
datey(valid_years_end + 0.001, strict = FALSE)
durationy(-(valid_duration_years_max + 0.001), strict = FALSE)
Whether a datey_interval includes a datey
Description
Test whether a datey_interval, [a,b), includes a datey t, i.e.
a \le t and t < b.
The %includes% operator is syntactic sugar for interval_includes().
An NA interval is treated as empty and an NA date is treated as not being in
any interval, so these methods are guaranteed to return TRUE or FALSE.
Usage
interval_includes(interval, value)
interval %includes% value
Arguments
interval |
The |
value |
The |
Value
A vector of logical corresponding to whether the interval
includes the value. Always TRUE or FALSE – NAs result in FALSE.
See Also
datey_interval, interval_properties, interval_nature, ops
Examples
t_2000 <- datey(2000)
t_2001 <- datey(2001)
t_2002 <- datey(2002)
t_2003 <- datey(2003)
t_2004 <- datey(2004)
interval <- t_2000 %to% t_2003
interval %includes% t_2000
interval %includes% t_2001 # Start of interval *is* included
interval %includes% t_2002
interval %includes% t_2003 # End of interval *not* included
interval %includes% t_2004
interval %includes% NA_datey_ # NAs are FALSE
NA_datey_interval_ %includes% t_2004 # NAs are FALSE
interval_includes(NA_datey_interval_, t_2002) # NAs are FALSE
# Function syntax:
interval_includes(interval, t_2002)
Properties of a datey_interval
Description
Test whether intervals, [a,b), are 'proper' or 'collapsed':
A proper interval does not end before its start, i.e.
a \le b.A collapsed interval does not start before its end, i.e.
a \ge b.
An NA interval is treated as collapsed and improper.
These definitions imply the following:
A collapsed interval could be empty or improper.
To test for an empty interval, i.e.
[a,a), test that it is both proper and collapsed.
These methods are guaranteed to return TRUE or FALSE, i.e. not NA
(provided the argument is an interval).
Vector versions mapping each element of x to TRUE or FALSE:
is_proper(x) tests whether the elements of x are proper.
is_collapsed(x) tests whether the elements of x are collapsed.
Scalar versions mapping x to a scalar TRUE or FALSE:
all_proper(x) tests whether all the elements of x are proper.
all_collapsed(x) tests whether all the elements of x are collapsed.
any_collapsed(x) tests whether at least one of the elements of x is
collapsed.
(any_proper() is not implemented because there is no obvious use case.)
These are S3 generic functions.
Usage
is_proper(x)
## Default S3 method:
is_proper(x)
## S3 method for class 'datey_interval'
is_proper(x)
all_proper(x)
## Default S3 method:
all_proper(x)
## S3 method for class 'datey_interval'
all_proper(x)
is_collapsed(x)
## Default S3 method:
is_collapsed(x)
## S3 method for class 'datey_interval'
is_collapsed(x)
all_collapsed(x)
## Default S3 method:
all_collapsed(x)
## S3 method for class 'datey_interval'
all_collapsed(x)
any_collapsed(x)
## Default S3 method:
any_collapsed(x)
## S3 method for class 'datey_interval'
any_collapsed(x)
Arguments
x |
The interval to test. |
Value
-
is_XXXfunctions return a logical vector corresponding the property. -
all_XXXandany_XXXfunctions return a logical scalar.
See Also
datey_interval, interval_properties, interval_includes
Examples
non_empty <- 1900 %to% 2000
empty <- 2000 %to% 2000
improper <- 2000 %to% 1900
na <- NA_datey_interval_
is_collapsed(non_empty) # FALSE
is_collapsed(empty) # TRUE
is_collapsed(improper) # TRUE
is_collapsed(na) # TRUE
is_proper(non_empty) # TRUE
is_proper(empty) # TRUE
is_proper(improper) # FALSE
is_proper(na) # FALSE
Get the start, end or duration of a datey_interval
Description
Get the start, end or duration of a datey_interval using the syntax
$start, $end or $duration respectively.
$duration is the duration of the interval provided it is proper
(i.e. start <= end).
If the interval is improper then $durationis NA_durationy_.
When x is a datey_interval then x$duration is identical to
durationy(x).
Usage
## S3 method for class 'datey_interval'
x$name
Arguments
x |
The |
name |
Must be |
Value
start and end return a vector of datey;
duration returns a vector of durationy.
See Also
datey_interval, interval_nature, interval_includes
Examples
t_1 <- start_day(2001, 1, 1)
t_2 <- start_day(2002, 2, 2)
interval <- datey_interval(t_1, t_2)
interval
interval$start
interval$end
interval$duration
Whether datey, durationy or
datey_interval are NA
Description
Valid datey system ranges:
Valid dates are from the start of 1000 to the start of 3000.
Valid durations are 2000 years or less in magnitude.
Values outside the above ranges are treated as NA.
is.na() tests whether a datey, durationy or
datey_interval is NA by element.
anyNA() tests whether any element of a datey, durationy or
datey_interval is NA.
For convenience,
the constants NA_datey_, NA_durationy_ and NA_datey_interval_ are the
datey,durationyanddatey_intervalversions of NA respectively, and-
integer constants describing the above valid ranges are also provided.
For performance reasons, intermediate datey system calculations are not required to check for NAs.
Throughout the datey package, NA will cause an error when used where
a datey_, durationy_ or datey_interval_ is expected.
This is because its type is logical and potentially indicates user
error. If you want an NA value with a datey system type, use one of NA_datey_, NA_durationy_
or NA_datey_interval_.
Usage
## S3 method for class 'datey'
is.na(x)
## S3 method for class 'datey'
anyNA(x, recursive = FALSE)
## S3 method for class 'datey_interval'
is.na(x)
## S3 method for class 'datey_interval'
anyNA(x, recursive = FALSE)
## S3 method for class 'durationy'
is.na(x)
## S3 method for class 'durationy'
anyNA(x, recursive = FALSE)
Arguments
x |
The |
recursive |
Currently required to be |
Value
is.na() returns a vector of logical the same length as x.
anyNA() always returns TRUE or FALSE, never NA and
never anything other than a single value.
See Also
NA_datey_, NA_durationy_, NA_datey_interval_, integer_constants, datey, durationy, datey_interval
Examples
t <- c(NA_datey_, datey(2000), datey(999.99, strict = FALSE))
is.na(t)
anyNA(t)
d <- c(NA_durationy_, durationy(1.5))
is.na(d)
anyNA(d)
i <- c(NA_datey_interval_, 2000 %to% 2001)
is.na(i)
anyNA(i)
Is x a leap year?
Description
Tests whether a date or year is a leap year.
This returns NA if the corresponding datey would be invalid, including
years before 1000 and dates after 3000-01-01.0.
For numerics, this returns NA for years values less than 1000 or greater
than 3000.
This is an S3 generic. This package provides methods for:
numeric types
doubleandinteger(interpreted as calendar years, e.g.2000.9means the calendar year 2000), anddate types
datey,Date,POSIXctandPOSIXlt.
Usage
is_leap_year(x)
## Default S3 method:
is_leap_year(x)
## S3 method for class 'integer'
is_leap_year(x)
## S3 method for class 'double'
is_leap_year(x)
## S3 method for class 'datey'
is_leap_year(x)
## S3 method for class 'Date'
is_leap_year(x)
## S3 method for class 'POSIXct'
is_leap_year(x)
## S3 method for class 'POSIXlt'
is_leap_year(x)
Arguments
x |
A vector date type or numeric year. |
Value
NA if x is not interpretable as a year or date, or outside [1000,3000],
TRUE if x is a leap year, otherwise
FALSE.
See Also
Examples
any(is_leap_year(c(1900, 1901, 2001))) #FALSE
all(is_leap_year(c(1904.1, 2000.5, 2004.9))) #TRUE
Is x a datey, durationy or datey_interval?
Description
These methods will always return a scalar logical TRUE or FALSE:
-
is_datey()tests whether an object is adatey. -
is_durationy()tests whether an object is adurationy. -
is_datey_interval()tests whether an object is adatey_interval.
Usage
is_datey(x)
is_datey_interval(x)
is_durationy(x)
Arguments
x |
The object to test. |
Value
A logical scalar indicating whether x a datey, durationy or
datey_interval as appropriate.
Always FALSE or TRUE; never NULL or NA.
Examples
t <- datey(2000:2001)
t
is_datey(t)
is_datey(NULL)
is_datey(NA)
d <- durationy(0:2)
d
is_durationy(d)
is_durationy(NULL)
is_durationy(NA)
interval <- datey(2000:2001) %to% datey(2001:2002)
interval
is_datey_interval(interval)
is_datey_interval(NULL)
is_datey_interval(NA)
Is a datey the start (or end) or middle of a day?
Description
is_start_day() checks whether x is the start or end of a day.
is_mid_day() checks whether x is the middle of a day.
These properties are not necessarily preserved when a duration of n years is added or subtracted.
Usage
is_start_day(x)
is_mid_day(x)
Arguments
x |
The |
Value
A vector of logical. Elements of the datey vector that are
NA_datey_ will result in NA elements of the result vector.
See Also
Examples
# Create (NA, 0 days, 1/4 day, 1/2 day):
t <- datey(c(NA_real_, 2000, 2000 + 0.25/366, 2000 + 0.5/366))
t # <NA> 2000-01-01.0 2000-01-01.25 2000-01-01.5
is_start_day(t) # NA TRUE FALSE FALSE
is_mid_day(t) # NA FALSE FALSE TRUE
# Properties are not necessarily preserved between years:
t <- start_day(2000,7,1) # Leap year
is_start_day(t) # TRUE
is_start_day(t + durationy(1)) # FALSE
Minimum, maximum or range of datey or durationy
Description
Gets the minimum, maximum or range of one or more datey or durationy
vectors. All arguments must be of the same type.
Returns a typed NA (NA_datey_ or NA_durationy_) for empty input or
when all values are NA and na.rm = TRUE.
These are S3 methods for the Summary group generic.
Usage
## S3 method for class 'datey_interval'
Summary(..., na.rm = FALSE)
## S3 method for class 'datey'
Summary(..., na.rm = FALSE)
## S3 method for class 'durationy'
Summary(..., na.rm = FALSE)
Arguments
... |
One or more |
na.rm |
A logical ( |
Value
min and max return a scalar.
range returns a two element vector,
the first element being the minimum and the second the maximum.
See Also
Examples
t <- datey(2000:2003)
t
min(t)
max(t)
range(t)
Mean value of datey or durationy
Description
Gets the mean value of a vector of datey or durationy as a scalar.
This will entail rounding if the mean of the underlying click counts is not an integer.
These are S3 methods for the mean generic.
Usage
## S3 method for class 'datey_interval'
mean(x, ..., na.rm = FALSE)
## S3 method for class 'datey'
mean(x, ..., na.rm = FALSE)
## S3 method for class 'durationy'
mean(x, ..., na.rm = FALSE)
Arguments
x |
The |
... |
Not used. |
na.rm |
A logical ( |
Value
A scalar of datey or durationy as appropriate.
See Also
Examples
t <- datey(2000:2003)
t
mean(t)
Operators for datey, durationy and datey_interval
Description
The unary - operator can be applied to a durationy to change its sign.
The following are the available binary operations on datey,durationy and
datey_interval only operands, and their meaning:
| Left | Operators | Right | Result | Notes |
datey | == != < <= > >= | datey | logical | Comparisons for dates |
durationy | == != < <= > >= | durationy | logical | Comparisons for durations |
datey_interval | == != | datey_interval | logical | Equality for date intervals |
datey | - | datey | durationy | Duration between two dates |
datey | + - | durationy | datey | A date offset by a duration |
durationy | + | datey | datey | A date offset by a duration |
durationy | + - | durationy | durationy | Duration addition and subtraction |
datey | %to% | datey | datey_interval | Create a date interval -- syntactic sugar for datey_interval() |
datey_interval | %includes% | datey | logical | Whether an interval includes a date -- syntactic sugar for interval_includes() |
datey_interval | & | datey_interval | datey_interval | Intersection of two date intervals -- NA_datey_interval_ if the intervals are disjoint and non-adjacent
|
dateys and durationys can also be mixed with numeric operands, in which case
the datey or durationy is first converted to years, The following
operations are implemented
Comparison, i.e. a
dateyordurationy==!=<<=>>=numeric or vice versa. Result islogical.-
dateyaddition and subtraction, i.e. adatey+-a numeric or vice versa. Result isdouble. -
durationyarithmetic, i.e. adurationy+-*/a numeric or vice versa. Result isdouble. The
%to%operator accepts numbers, which are treated as years and coerced todatey.The
%includes%operator accepts a number as its right hand operand, which is treated as years and coerced todatey.
When applied to datey_intervals, & is the 'intersection' operator.
For intervals that do not intersect the result of &
depends on whether the intervals are adjacent. If they are adjacent then the result
is an empty interval starting (and ending) at the point in time they touch.
Otherwise it is NA_datey_interval_. You can test whether intervals
a and b intersect using is_collapsed(a & b).
Throughout the datey package, NA will cause an error when used where
a datey_, durationy_ or datey_interval_ is expected.
This is because its type is logical and potentially indicates user
error. If you want an NA value with a datey system type, use one of NA_datey_, NA_durationy_
or NA_datey_interval_.
Usage
## S3 method for class 'datey_type'
Ops(e1, e2)
Arguments
e1 |
First parameter. |
e2 |
Second parameter (missing if a unary operator). |
Value
See above table. In essence
subtracting two
dateys results in adurationy,comparing two
Ts results in a logical,adding or subtracting a
durationyto or from aTresults in aT, andmixing
durationyanddateywith numeric operands first converts thedurationyanddateyto years and then results in standard numeric evaluation,
where T is either datey or durationy in each of the above.
See Also
datey, durationy, datey_interval,
vignette("datey", package = "datey") for a worked introduction
Examples
t_2000 <- datey(2000)
t_2001 <- datey(2001)
d_0.5 <- durationy(0.5)
t_2000
t_2001
d_0.5
t_2001 - t_2000 # `datey` - `datey` is a `durationy`
t_2000 + d_0.5 # `datey` + `durationy` is a `datey`
t_2001 - d_0.5 # `datey` - `durationy` is a `datey`
t_2000 + 0.5 # Arithmetic with numerics results in a double
d_0.5 + d_0.5 # `durationy` + `durationy` is a `durationy`
d_0.5 + 0.5 # Arithmetic with numerics results in a double
d_0.5 * 2 # Arithmetic with numerics results in a double
interval <- t_2000 %to% t_2001
interval
# %to% also accepts numbers:
2000 %to% 2001
interval %includes% t_2000 # TRUE -- start *is* included in an interval
interval %includes% (t_2000 + d_0.5) # TRUE
interval %includes% t_2001 # FALSE -- end is *not* included in an interval
# %includes% also accepts a number as its right hand operand:
interval %includes% 2000.5
# %includes% handling of NAs:
interval %includes% NA_datey_ # FALSE (not NA)
NA_datey_interval_ %includes% t_2000 # FALSE (not NA)
(2000 %to% 2020) & (2010 %to% 2030) # [2010-01-01.0, 2020-01-01.0)
# Non-intersecting *adjacent* intervals:
(2000 %to% 2001) & (2001 %to% 2002) # [2001-01-01.0, 2001-01-01.0)
# Non-intersecting *non*-adjacent intervals:
(1900 %to% 1901) & (2001 %to% 2001) # <NA>
Create datey or durationy sequence vector
Description
Creates a datey or durationy vector by defining a sequence.
Usage
## S3 method for class 'datey'
seq(from, to, by, ...)
## S3 method for class 'durationy'
seq(from, to, by, ...)
Arguments
from |
The first value in the sequence.
A scalar |
to |
The sequence stops before values exceed |
by |
The increment of the sequence.
A scalar |
... |
Not used. |
Value
The sequence as a vector of datey (for seq.datey) or
durationy (for seq.durationy).
See Also
Examples
seq(from = datey(2000), to = datey(2005), by = durationy(2))
seq(from = datey(2000), to = datey(1999), by = durationy(-0.25))
Subset datey, durationy or datey_interval vectors
Description
Subsets datey, durationy or datey_interval vectors.
Usage
## S3 method for class 'datey'
x[i, ...]
## S3 method for class 'durationy'
x[i, ...]
## S3 method for class 'datey_interval'
x[i, ...]
## S3 replacement method for class 'datey'
x[i] <- value
## S3 replacement method for class 'durationy'
x[i] <- value
## S3 replacement method for class 'datey_interval'
x[i] <- value
Arguments
x |
A |
i |
Indices to extract. |
... |
Other arguments. |
value |
Value to assign. |
Value
The subset.
See Also
datey, durationy, datey_interval, combine
Examples
x <- datey(2001:2004)
x
x[2:3]
x[2:3] <- datey(1999)
x
Format or print a datey
Description
A datey is printed as either
-
YYYY-MM-DD, i.e. ISO 8601 extended date format, or -
YYYY-MM-DD.F...where.F...is the day fraction part.
If include_day_fraction is TRUE then [.F...] is included even if it
is 0 (i.e. .0).
Note that a datey created as the end of a day (or with day fraction 1) will
print as the start of the following day.
Usage
## S3 method for class 'datey'
as.character(x, ...)
## S3 method for class 'datey'
format(x, include_day_fraction = TRUE, ...)
## S3 method for class 'datey'
print(x, include_day_fraction = TRUE, max = NULL, ...)
Arguments
x |
The |
... |
Other arguments. |
include_day_fraction |
Whether to include the fractional day part.
Defaults to |
max |
Numeric or |
Value
as.character and format return a vector of character.
print invisibly returns x.
See Also
Examples
start <- start_day(2001, 2, 3)
fractional <- datey( 2001, 2, 3, day_fraction = 0.4444)
mid <- mid_day( 2001, 2, 3)
end <- end_day( 2001, 2, 3)
format(start) # "2001-02-03.0"
format(start, include_day_fraction = FALSE) # "2001-02-03"
format(fractional) # "2001-02-03.4447"
format(mid) # "2001-02-03.5"
format(end) # "2001-02-04.0"
Format or print a datey_interval
Description
A datey_interval is printed as "[start, end)", where start and end are
printed either as
-
YYYY-MM-DD, i.e. ISO 8601 extended date format, or -
YYYY-MM-DD.F...where.F...is the day fraction part.
If include_day_fraction is TRUE then [.F...] is included even if it
is 0 (i.e. .0).
Usage
## S3 method for class 'datey_interval'
as.character(x, ...)
## S3 method for class 'datey_interval'
format(x, include_day_fraction = TRUE, ...)
## S3 method for class 'datey_interval'
print(x, include_day_fraction = TRUE, max = NULL, ...)
Arguments
x |
The |
... |
Further arguments to be passed from or to other methods. |
include_day_fraction |
Whether to include the fractional day part.
Defaults to |
max |
Numeric or |
Value
as.character and format return a vector of character.
print invisibly returns x.
See Also
Format or print a durationy
Description
A durationy is printed as a decimal.
This format is readable by durationy.character().
Usage
## S3 method for class 'durationy'
as.character(x, ...)
## S3 method for class 'durationy'
format(x, include_plus = FALSE, use_true_minus = TRUE, year_unit = "yr", ...)
## S3 method for class 'durationy'
print(
x,
include_plus = FALSE,
use_true_minus = TRUE,
year_unit = "yr",
max = NULL,
...
)
Arguments
x |
The |
... |
Other arguments. |
include_plus |
Whether to include a plus ('+') sign for positive
durations.
Defaults to |
use_true_minus |
Whether to use the
true minus sign ('-', U+2212)
sign as opposed to the
ASCII hyphen (-, U+002D).
Defaults to |
year_unit |
The year unit name to print.
If not blank then the value is followed by a space and the unit.
Cannot be more than 20 characters (UTF-8 bytes) or contain control characters.
Defaults to |
max |
Numeric or |
Value
as.character and format return a vector of character.
print invisibly returns x.
See Also
Examples
pos <- durationy(1)
neg <- durationy(-2.3)
format(pos) # "1 yr"
format(pos, include_plus = TRUE) # "+1 yr"
format(pos, year_unit = "") # "1"
format(neg) # U+2212 (true minus) followed by "2.3" (CRAN-compliance)
format(neg, use_true_minus = FALSE) # "-2.3 yr"
format(neg, use_true_minus = FALSE, year_unit = "a") # "-2.3 a"