| Title: | Mixed Temporal Vectors and Operations |
| Version: | 0.3.0 |
| Description: | Flexible time classes for time series analysis and forecasting with mixed temporal granularities. Supports linear and cyclical time representations in discrete and continuous forms, with timezone support, across multiple calendar systems including Gregorian and ISO week date calendars. Time points are stored numerically relative to a chronon; an atomic time granule defined by time units of a calendar. Calendrical arithmetic enables conversion between time granules (e.g. days to months) and calendar systems. Multi-unit arithmetic allows for temporal analysis with other granules of common calendars (e.g. fortnights are 2-week units). Time vectors of different granularities (e.g. monthly and quarterly) can be combined in a single vector, making 'mixtime' ideal for data that changes observation frequency over time or requires temporal reconciliation across scales. The package is extensible, allowing users to define custom calendars that build upon civil and astronomical time systems. |
| License: | MIT + file LICENSE |
| URL: | https://pkg.mitchelloharawild.com/mixtime/, https://github.com/mitchelloharawild/mixtime |
| BugReports: | https://github.com/mitchelloharawild/mixtime/issues |
| Encoding: | UTF-8 |
| Language: | en-GB |
| Depends: | R (≥ 3.0.2) |
| Imports: | lifecycle, vctrs, rlang, cli, S7, vecvec (≥ 1.2.0), tzdb, methods |
| Suggests: | stats, tsibble, testthat, pillar, knitr, rmarkdown, ggplot2, ggtime |
| LinkingTo: | cpp11 (≥ 0.5.2), tzdb (≥ 0.5.0) |
| RdMacros: | lifecycle |
| VignetteBuilder: | knitr |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | yes |
| Packaged: | 2026-08-24 04:50:59 UTC; mitchell |
| Author: | Mitchell O'Hara-Wild
|
| Maintainer: | Mitchell O'Hara-Wild <mail@mitchelloharawild.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-24 05:30:02 UTC |
mixtime: Mixed Temporal Vectors and Operations
Description
Flexible time classes for time series analysis and forecasting with mixed temporal granularities. Supports linear and cyclical time representations in discrete and continuous forms, with timezone support, across multiple calendar systems including Gregorian and ISO week date calendars. Time points are stored numerically relative to a chronon; an atomic time granule defined by time units of a calendar. Calendrical arithmetic enables conversion between time granules (e.g. days to months) and calendar systems. Multi-unit arithmetic allows for temporal analysis with other granules of common calendars (e.g. fortnights are 2-week units). Time vectors of different granularities (e.g. monthly and quarterly) can be combined in a single vector, making 'mixtime' ideal for data that changes observation frequency over time or requires temporal reconciliation across scales. The package is extensible, allowing users to define custom calendars that build upon civil and astronomical time systems.
Author(s)
Maintainer: Mitchell O'Hara-Wild mail@mitchelloharawild.com (ORCID)
Authors:
Mitchell O'Hara-Wild mail@mitchelloharawild.com (ORCID)
See Also
Useful links:
Report bugs at https://github.com/mitchelloharawild/mixtime/issues
Tolerant comparison of mixtime time values
Description
vecvec::class_vecvec's all.equal() method (which mixtime inherits,
since a mixtime vector is a vecvec) handles length/NA mismatches and
groups elements by their underlying storage slot, then compares each
group's raw values with all.equal(). That raw comparison has no notion
of chronon: two elements that are == (e.g. days(1) and hours(24), or
a yearmonth and an equivalent-instant yearweek) can end up stored with
different chronons or magnitudes, and so are wrongly reported as unequal.
This method fixes that at the per-slot level: elements already == (which
is chronon-aware, see mt_linear-compare/mt_duration-compare) count as
equal outright; for the rest, the discrepancy is measured as the duration
between them in their common chronon. A time point has no "typical
magnitude" to scale a relative tolerance against the way a plain number
does, so - unlike base::all.equal.numeric() - tolerance is always
absolute, in (possibly fractional) chronon units.
Usage
## S3 method for class ''mixtime::mt_time''
all.equal(target, current, tolerance = sqrt(.Machine$double.eps), ...)
Arguments
target, current |
|
tolerance |
Numeric tolerance, as an absolute number of |
... |
Ignored. |
Value
TRUE if target and current are equal within tolerance,
otherwise a string describing the discrepancy.
Examples
all.equal(yearmonth(0), yearmonth(0))
all.equal(yearmonth(0), yearmonth(1))
all.equal(days(1), hours(24))
Convert a time class into a mixtime
Description
Coerces a time object (e.g. Date, POSIXct, yearmonth) to a mixtime
vector using vctrs::vec_cast(). The chronon and cycle are inferred from
x via time_chronon() and time_cycle().
Usage
as_mixtime(x, ...)
Arguments
x |
A time value to convert to a |
... |
Additional arguments passed to the underlying |
Value
A mixtime object corresponding to x.
See Also
mixtime() for constructing a mixtime directly from data,
is_mixtime() for testing if an object is a mixtime.
Examples
as_mixtime(Sys.Date())
as_mixtime(Sys.time())
Gregorian time unit classes
Description
Time unit constructors for the Gregorian calendar system. These units can be
used with linear_time() to create custom time representations.
Usage
cal_gregorian
Format
A civil-based calendar containing Gregorian time units.
Details
The following time units are available in the Gregorian calendar (cal_gregorian$).
-
year(): Year unit -
quarter(): Quarter (3-month period) unit -
month(): Month unit -
day(): Day unit -
hour(): Hour unit -
minute(): Minute unit -
second(): Second unit -
millisecond(): Millisecond unit
These units form a hierarchy where conversions between adjacent units follow the Gregorian calendar rules. For units that don't have a fixed relationship (e.g., months to days), the conversion requires a time context.
Value
An S3 list of class c("cal_gregorian", "mt_calendar") containing
the named time unit classes of the Gregorian calendar. Each unit is
accessible via $ notation and calling it with a step size produces a
time granule (e.g., 1 month granule as cal_gregorian$month(1L)).
See Also
linear_time() for creating linear time points.
Examples
# Create a custom time representation using Gregorian units
linear_time(
Sys.time(),
chronon = hour(1L)
)
ISO 8601 time unit classes
Description
Time unit constructors for the ISO 8601 calendar system. These units can be
used with linear_time() to create custom time representations.
Usage
cal_isoweek
Format
A civil-based calendar containing ISO 8601 time units.
Details
The following time units are available in the ISO week date calendar:
-
year(): ISO year unit (years start on the week containing the first Thursday) -
week(): Week unit (7-day periods) -
day(): Day unit -
hour(): Hour unit -
minute(): Minute unit -
second(): Second unit -
millisecond(): Millisecond unit
ISO 8601 weeks always start on Monday and the first week of a year is the week containing the first Thursday of that year. This means that some days in early January may belong to the last week of the previous ISO year, and some days in late December may belong to the first week of the next ISO year.
Value
An S3 list of class c("cal_isoweek", "mt_calendar") containing
the named time unit classes of the ISO 8601 week calendar. Each unit is
accessible via $ notation and calling it with a step size produces a
time granule (e.g., 1 week granule as cal_isoweek$week(1L)).
See Also
linear_time() for creating custom time representations,
yearweek() for a pre-defined ISO 8601 year-week representation
Symmetry454 time unit classes
Description
Time unit constructors for the Symmetry454 calendar system. These units can be
used with linear_time() to create custom time representations.
Usage
cal_sym454
Format
A civil-based calendar containing Symmetry454 time units.
Details
The Symmetry454 calendar (Sym454) is a perennial solar calendar proposed by Dr. Irv Bromberg. It preserves the traditional 12-month structure and 7-day week, with months arranged in a symmetrical 4-5-4 week pattern per quarter. Every month starts on Monday and has a whole number of weeks, meaning no month ever contains a partial week.
The following time units are available in the Symmetry454 calendar (cal_sym454$).
-
year(): Year unit -
month(): Month unit -
week(): Week unit -
day(): Day unit -
hour(): Hour unit -
minute(): Minute unit -
second(): Second unit -
millisecond(): Millisecond unit
Leap years
Rather than intercalary days, Symmetry454 uses a leap week appended to
December once every 5 or 6 years, making December a 5-week month in leap
years. A year is a leap year if (52 * year + 146) %% 293 < 52.
This yields a mean year of 365 + 71/293 days (approx 365 days, 5 hours, 48 minutes, 56.5 seconds), intentionally slightly shorter than the mean northward equinoctial year.
Value
An S3 list of class c("cal_sym454", "mt_calendar") containing
the named time unit classes of the Symmetry454 calendar. Each unit is
accessible via $ notation and calling it with a step size produces a
time granule (e.g., 1 week granule as cal_sym454$week(1L)).
See Also
linear_time() for creating linear time points, and
https://en.wikipedia.org/wiki/Symmetry454 for more calendar details.
Examples
# Create a custom time representation using Symmetry454 units
linear_time(
Sys.time(),
chronon = cal_sym454$week(1L)
)
Civil time unit classes
Description
Time unit constructors for the civil time system where the boundary of each
day is at midnight on the 24 hour clock. This calendar is intended to be
built on by other calendars (e.g. [cal_time_civil] and [cal_isoweek]) to
add common time components. These units can be
used with linear_time() to create custom time representations.
Usage
cal_time_civil
Details
The following time units are available (cal_time_civil$).
-
day(): Day unit -
hour(): Hour unit -
minute(): Minute unit -
second(): Second unit -
millisecond(): Millisecond unit -
microsecond(): Microsecond unit -
nanosecond(): Nanosecond unit
Value
A time granule object for the civil time system.
See Also
Examples
# Create a custom time representation using civil time granules
hms <- new_cyclical_time_fn(
chronon = second(1L),
cycle = hour(1L)
)
Lunar time unit classes
Description
Time unit constructors for the synodic lunar time system, where the boundary
of each month is at the new moon (lunar conjunction) and the boundary of
each phase is at a lunar octant (each eighth of the synodic cycle). Both
boundaries are location-independent, as the new moon is a geocentric
astronomical event. cal_time_lunar is an alias for
cal_time_lunar_synodic.
Usage
cal_time_lunar_synodic
cal_time_lunar
Format
A calendar containing synodic lunar time units.
Details
The following time units are available in the lunar calendar systems.
-
month(): Synodic month unit -
phase(): Synodic phase unit
Value
An S3 list of class c("cal_time_lunar", "mt_calendar") containing
the named time unit classes of the synodic lunar calendar. Each unit is
accessible via $ notation and calling it with a step size produces a
time granule (e.g., 1 synodic month granule as
cal_time_lunar$month(1L)). Lunar month and phase boundaries are
location-independent.
See Also
cal_time_civil, cal_time_solar
Examples
# Find the time of a new moon in the Gregorian calendar
t <- linear_time(Sys.Date(), cal_time_lunar$month(1L))
datetime(t, tz = "Australia/Melbourne")
Solar time unit classes
Description
Time unit constructors for the transit-based solar time system, where the
boundary of each day is at apparent solar midnight. Solar events define the
ampm (midnight and noon) and illumination (dawn, sunrise, sunset, dusk)
units. cal_time_solar is an alias for cal_time_solar_transit.
Usage
cal_time_solar_transit
cal_time_solar
Format
A location-based calendar containing transit-based solar time units.
Details
The following time units are available in the solar calendar systems.
-
day(): Day unit -
ampm(): Half-day units (AM = before solar noon, PM = after solar noon) -
hour(): Hour units within the solar day -
minute(): Minute units within the solar hour -
second(): Second units within the solar minute -
degree(): Solar angle units within the day -
arcminute(): Arcminute units within the solar degree -
arcsecond(): Arcsecond units within the solar arcminute -
illumination(): Illumination phases (night, astronomical/nautical/civil dawn, day, civil/nautical/astronomical dusk)
AM/PM half-days
The ampm unit divides each solar day into two halves between solar noon and
solar midnight:
| Half | Period | Description |
| AM | Solar midnight to noon | Morning half; before solar transit |
| PM | Solar noon to midnight | Afternoon half; after solar transit |
Solar illumination phases
Phases describe the illumination state of the sky and correspond to standard twilight definitions used in astronomy and navigation. Each phase is bounded by a pair of solar altitude thresholds:
| Phase | Solar altitude range | Description |
| Night | < -18° | Sky fully dark; from last dusk to first dawn (spans noon) |
| Astronomical dawn | -18° to -12° | Astronomical twilight before sunrise; faint objects obscured |
| Nautical dawn | -12° to -6° | Nautical twilight before sunrise; horizon visible at sea |
| Civil dawn | -6° to -0.833° | Civil twilight before sunrise; sky brightening in the east |
| Day | > -0.833° | Sun above the horizon; spans solar noon |
| Civil dusk | -0.833° to -6° | Civil twilight after sunset; sky fading in the west |
| Nautical dusk | -6° to -12° | Nautical twilight after sunset; horizon visible at sea |
| Astronomical dusk | -12° to -18° | Astronomical twilight after sunset; faint objects obscured |
The -0.833° threshold for sunrise and sunset accounts for the mean angular radius of the solar disc (0.267°) plus the standard atmospheric refraction at the horizon (0.566°). Noon and midnight are derived from the equation of time rather than a fixed altitude. Locations that experience polar day or polar night (civil days where sunrise does not occur) are not currently supported, it is recommended to use an alternative reference location.
Value
An S3 list of class c("cal_time_solar", "mt_calendar") containing
the named time unit classes of the solar transit calendar. Each unit is
accessible via $ notation and calling it with a step size and location
produces a time granule (e.g., 1 solar day granule as
cal_time_solar$day(1L, lat = 0, lon = 0)). Because solar day boundaries
depend on the observer's position, each unit constructor requires lat
and lon arguments.
See Also
cal_time_civil, cal_time_lunar
Examples
# Find the current solar time in Melbourne
datetime(Sys.time(), calendar = cal_time_solar, lat = -37.8136, lon = 144.9631)
Cardinality between time granules
Description
This S7 generic function defines the calendrical relationships between two
chronons, and is one of the building block for defining calendars in mixtime.
It calculates how many x chronons fit into the y chronon. Some chronon
sizes are context-dependent (such as the number of days in a month),
and so an optional time point defined in terms of y chronons can be
provided with at.
Usage
chronon_cardinality(x, y, ...)
Arguments
x |
The finer time granule (e.g. |
y |
The coarser time granule (e.g. |
... |
Additional arguments for methods. |
Details
The methods are dispatched based on the shortest path along defined methods. This allows for defining only the direct relationships between adjacent time units, and relying on graph traversal to find how to convert between more distant units. For example the number of seconds in an hour can be calculated from the number of seconds in a minute and then number of minutes in an hour.
If a method is defined for converting between time units of different calendar systems (e.g., Gregorian calendar days to Chinese calendar days), then that method can be used to convert times at any granularity between the two systems.
Value
Numeric describing how many x time granules fit into y at time at.
Examples
# There are 12 months in a year
with(cal_gregorian, chronon_cardinality(month(1L), year(1L)))
# There are 7 days in a week
with(cal_isoweek, chronon_cardinality(day(1L), week(1L)))
# There are 3600 seconds in an hour
with(cal_gregorian, chronon_cardinality(second(1L), hour(1L)))
# There are 18 "2 months" in 3 years
with(cal_gregorian, chronon_cardinality(month(2L), year(3L)))
# There are 365 days in 2025 (a common year)
chronon_cardinality(
cal_gregorian$day(1L), cal_gregorian$year(1L),
at = year(as.Date("2025-01-01"))
)
# There are 366 days in 2024 (a leap year)
chronon_cardinality(
cal_gregorian$day(1L), cal_gregorian$year(1L),
at = mixtime::year(as.Date("2024-01-01"))
)
# There are 29 days in February 2024 (a leap year)
chronon_cardinality(
cal_gregorian$day(1L), cal_gregorian$month(1L),
at = yearmonth(as.Date("2024-02-01"))
)
Fixed cardinality between time granules
Description
A restricted variant of chronon_cardinality() for time granule pairs
whose relationship is a constant, context-independent number (e.g., 60
seconds in a minute, 24 hours in a day). Unlike chronon_cardinality(),
methods for this generic do not receive (and must not need) an at time
point, and should return the number of unit (n = 1L) x granules that
fit within one unit y granule.
Usage
chronon_cardinality_fixed(x, y, ...)
Arguments
x |
The finer time granule (e.g. |
y |
The coarser time granule (e.g. |
... |
Additional arguments for methods. |
Details
Defining a method for chronon_cardinality_fixed() automatically provides
a chronon_cardinality() method for the pair (scaled by the requested
granule sizes via the list(mt_unit, mt_unit) fallback method), and marks
the relationship as safe to use for chronon_divmod()'s graph traversal,
where variable (context-dependent) cardinalities cannot be used since no
at is available mid-traversal.
Value
A single number describing how many unit x time granules fit
into a unit y time granule.
Find the common chronon of a time object
Description
This utility function takes a set of chronons and identifies a common chronon of the finest granularity that can represent all input chronons without loss of information. This is useful for operations that require a shared time granule, such as combining or comparing different time measured at different precisions.
The result is obtained by finding the greatest lower bound (GLB) of the input
chronons using the ordered relationships defined by chronon_cardinality()
methods. The GLB represents the finest chronon that can represent all input
chronons without loss of information.
Usage
chronon_common(x, ...)
chronon_common.mixtime(x, .ptype = NULL, ...)
Arguments
x |
A time object (typically a |
... |
Additional arguments for methods. |
.ptype |
If NULL, the default, the output returns the common chronon
across all chronons of |
Value
A time granule object representing the common chronon.
Examples
# The common chronon between a year-month and a day is a day
chronon_common(c(yearmonth(Sys.Date()), date(Sys.Date())))
# The common chronon between a Gregorian month and an ISO week is a day
chronon_common(c(yearmonth(Sys.Date()), yearweek(Sys.Date())))
# The common chronon between a ISO week and an hour is an hour
chronon_common(c(yearweek(Sys.Date()), linear_time(Sys.time(), hour(1L))))
Convert between chronons of different time granules
Description
This function converts between chronons measured in different time granules.
It is used internally for converting between different continuous time types,
and is particularly useful for efficiently converting between irregular time
granules. The default method uses chronon_cardinality() to cast between
time granules, which is efficient for regular time granules.
Usage
chronon_divmod(from, to, ...)
Arguments
from |
The time granule that |
to |
The time granule to convert |
... |
Additional arguments for methods. |
Value
An list of two elements:
-
div: integer vector of chronons measured in thetotime granule. -
mod: integer vector of the remainder (infromtime granule) after converting to thetotime granule.
Examples
# Convert day 16 after epoch (1970-01-01) into weeks since epoch (and remainder days)
with(cal_isoweek, chronon_divmod(day(1L), week(1L), 16L))
# Convert week 4 after epoch (1970-W1) into days since epoch
with(cal_isoweek, chronon_divmod(week(1L), day(1L), 4L))
Epoch offset for chronons
Description
Returns the epoch offset for a given chronon (time unit). The epoch defines the starting point of the chronon's linear numbering, used when converting from internal representations to common displays (e.g. applying an epoch of 1970-01-01).
Usage
chronon_epoch(x, ...)
Arguments
x |
A chronon (time unit) object. |
... |
Additional arguments for methods. |
Value
A numeric value representing the epoch for the chronon.
Examples
# The epoch for year linear time displays is 1970
chronon_epoch(cal_gregorian$year(1L))
Default formatting strings for chronon attributes
Description
Provides suffixes for default formatting strings for a given chronon (time granule). This provides useful information such as timezones or locations in the string.
Usage
chronon_format_attr(x, ...)
Arguments
x |
A chronon (time granule) object. |
... |
Additional arguments for methods. |
Value
A character string containing the default format suffix for the chronon.
Default formatting strings for chronons
Description
Provides default linear time formatting strings for a given chronon (finest
time granule). The format strings use placeholders like {lin(year(1L))},
{cyc(month(1L), year(1L)} and {cyc(day(1L), month(1L)}, which are
evaluated in the context of the data's time_calendar().
Usage
chronon_format_linear(x, cal = time_calendar(x), ...)
chronon_format_cyclical(x, y, ...)
chronon_format_duration(x, ...)
Arguments
x |
A time granule for the chronon. |
cal |
The calendar of the chronon, used to disambiguate suitable format
strings for time units that are shared across calendars (e.g.
|
... |
Additional arguments for methods. |
y |
A time granule for the cycle |
Value
A character string containing the default format template for the chronon.
Examples
chronon_format_linear(cal_gregorian$year(1L))
chronon_format_linear(cal_gregorian$month(1L))
chronon_format_linear(cal_gregorian$day(1L))
chronon_format_linear(cal_isoweek$day(1L))
chronon_format_cyclical(cal_gregorian$month(1L), cal_gregorian$year(1L))
chronon_format_cyclical(cal_gregorian$day(1L), cal_gregorian$month(1L))
chronon_format_cyclical(cal_isoweek$day(1L), cal_isoweek$week(1L))
chronon_format_cyclical(cal_isoweek$week(1L), cal_isoweek$year(1L))
chronon_format_duration(cal_gregorian$year(1L))
chronon_format_duration(cal_gregorian$month(1L))
chronon_format_duration(cal_gregorian$day(1L))
Default parsing format strings for chronons
Description
Provides candidate format strings for parsing text into a given chronon
(finest time granule), for use as the format argument of
time_parse(). Dispatches the same way as
chronon_format_linear()/chronon_format_cyclical(), but returns every
common format instead of a single default, so time_parse() can try each
in turn and keep whichever parses the most values. Methods should build
their return value with parse_format().
Usage
chronon_parse_linear(x, cal = time_calendar(x), ...)
chronon_parse_cyclical(x, y, ...)
Arguments
x |
A time granule for the chronon. |
cal |
The calendar of the chronon, used to disambiguate suitable format
strings for time units that are shared across calendars (e.g.
|
... |
Additional arguments for methods. |
y |
A time granule for the cycle |
Value
A character vector of format templates, ordered from most to
least common, built with parse_format(). The first element typically
matches chronon_format_linear() (for chronon_parse_linear()) or
chronon_format_cyclical() (for chronon_parse_cyclical()) for the
same chronon.
See Also
parse_format() for building candidate format strings (what
these methods are built from), time_parse() for using the result as
candidate formats, chronon_format_linear()/chronon_format_cyclical()
for the single default format these are based on.
Examples
chronon_parse_linear(cal_gregorian$year(1L))
chronon_parse_linear(cal_gregorian$month(1L))
chronon_parse_linear(cal_gregorian$day(1L))
chronon_parse_linear(cal_isoweek$day(1L))
chronon_parse_cyclical(cal_gregorian$month(1L), cal_gregorian$year(1L))
chronon_parse_cyclical(cal_isoweek$day(1L), cal_isoweek$week(1L))
Compute circular rolling sums
Description
Calculates rolling sums of length k for all contiguous subsequences
around a circular vector. Returns sums for each valid k-element window
that wraps around the vector as if arranged in a circle.
Usage
circsum(x, size, step = size)
Arguments
x |
A numeric vector to compute circular sums over. |
size |
Integer; the window size (number of consecutive elements to sum). A negative size anchors the window at its end, with the window counting backwards. |
step |
Integer; the step size (the increment in starting index for each sum). A negative step walks the windows backwards around the circle. |
Value
A numeric vector containing the sum of each contiguous subsequence
around the circle. The length of the resulting vector is the number of
combinations until the pattern between x and step repeats
Examples
# Simple circular sum with window of 2
circsum(c(1, 2, 3, 4), 2)
# Returns: 3 7 (1+2, 3+4)
# Window of 3 elements
circsum(c(1, 2, 3, 4, 5), 3)
# Returns: 6 10 9 8 12 (1+2+3, 4+5+1, 2+3+4, 5+1+2, 3+4+5)
# Negative step walks the same windows backwards
circsum(c(1, 2, 3, 4, 5), 1, -1)
# Returns: 1 5 4 3 2
# Negative size anchors each window at its end instead of its start - a
# trailing rather than leading rolling sum
circsum(c(1, 2, 3, 4, 5), -2, 1)
# Returns: 6 3 5 7 9 (5+1, 1+2, 2+3, 3+4, 4+5)
Base S7 class for mixtime vector objects
Description
class_mixtime is the base S7 class for all mixtime vector objects,
inheriting from vecvec::class_vecvec. While not intended to be used
directly, this S7 class is suitable to use when defining S7 methods for
mixtime vectors. S3 methods can be defined using the mixtime::mixtime
class.
Usage
class_mixtime(x = list(), i = seq_len(sum(lengths(x))))
Arguments
x |
A list of |
i |
A vector of integers specifying the location of each element in |
Value
When used as a class definition (e.g., in S7::method(generic, class_mixtime)), an S7 class object representing the mixtime class,
inheriting from vecvec::class_vecvec. When called as a constructor
(class_mixtime(list(...))), a mixtime vector of S7 class mixtime
(also inheriting the S3 class "mixtime"), containing the supplied list
of time vectors as a vecvec::class_vecvec structure. End users should
prefer mixtime() or new_mixtime() for construction.
See Also
mixtime() for creating mixtime vectors, and new_mixtime() for
the low-level constructor function of this S7 class.
Linear and cyclical component helpers
Description
lin() and cyc() name the time components addressed by mixtime's
component-aware contexts — a single vocabulary shared across format() (and
parsing) format strings and time_components() expressions. They are only
meaningful inside one of these contexts; calling them directly is an error.
Usage
lin(granule)
cyc(granule, cycle)
Arguments
granule |
The time granule to address, given as a granule generator (e.g.
|
cycle |
The coarser granule defining the cycle a |
Details
A linear and a cyclical component of the same granule store the same value:
the count of that chronon since the Unix epoch. The reduction to a within-cycle
position happens only when a cyclical vector is formatted. cyc() therefore
behaves like lin() on its finest granule but additionally records the cycle.
Value
A component specification, consumed internally by the component-aware
context (e.g. format() or time_components()).
See Also
format() and time_components()
Cyclical time points
Description
cyclical_time() creates a vector of cyclical time points representing
positions within repeating cycles. This function is useful for creating custom
cyclical time representations that aren't covered by the convenience functions
like day_of_week() or month_of_year().
Usage
cyclical_time(
data,
chronon = time_chronon(data),
cycle = time_cycle(data),
discrete = TRUE,
calendar = time_calendar(data)
)
Arguments
data |
Input data to convert to cyclical time. Can be:
|
chronon |
A time granule representing the chronon (finest
indivisible time granule), evaluated in the context of |
cycle |
A time granule representing the cycle (coarser time granule
that defines the period), evaluated in the context of |
discrete |
Logical. If |
calendar |
Calendar system used to evaluate |
Value
A mixtime time vector containing an mt_cyclical vector.
See Also
-
new_cyclical_time_fn()for creating reusable cyclical time functions -
day_of_week(),day_of_month(),day_of_year()for common cyclical representations -
month_of_year(),week_of_year()for other cyclical time helpers -
cal_gregorian, cal_isoweek for calendar systems
Examples
# Day of week (1-7, Monday = 1)
cyclical_time(
Sys.Date(),
chronon = day(1L),
cycle = week(1L),
calendar = cal_isoweek
)
# Month of year (1-12)
cyclical_time(
Sys.Date(),
chronon = month(1L),
cycle = year(1L)
)
# Continuous time (discrete = FALSE) for fractional month of year
cyclical_time(
Sys.Date(),
chronon = month(1L),
cycle = year(1L),
discrete = FALSE
)
# Day of month with Gregorian calendar
cyclical_time(
Sys.Date(),
chronon = day(1L),
cycle = month(1L),
calendar = cal_gregorian
)
# Hours, minutes, and seconds
cyclical_time(
Sys.time(),
chronon = second(1L),
cycle = day(1L)
)
Cyclical time helpers
Description
Helper functions for creating cyclical time representations. These functions create time objects that repeat within a larger time cycle, useful for identifying seasonal patterns or positions within a calendar period.
Usage
month_of_year(data, discrete = TRUE, calendar = time_calendar(data), ...)
day_of_year(data, discrete = TRUE, calendar = time_calendar(data), ...)
day_of_month(data, discrete = TRUE, calendar = time_calendar(data), ...)
time_of_day(data, discrete = TRUE, calendar = time_calendar(data), ...)
day_of_week(data, discrete = TRUE, calendar = time_calendar(data), ...)
week_of_year(data, discrete = TRUE, calendar = time_calendar(data), ...)
Arguments
data |
Another object to be coerced into the specified cyclical time. |
discrete |
If |
calendar |
A calendar object specifying the calendar system to use. |
... |
Additional arguments for |
Value
A mixtime time vector containing an mt_cyclical vector with chronon and cycle matching the function used.
Cyclical time representations
-
day_of_week(): Represents the day position within a week (1-7) using the ISO 8601 standard where weeks start on Monday. -
day_of_month(): Represents the day position within a month (1-28, 1-29, 1-30, or 1-31 depending on the month). The chronon is one day, cycling within a month. -
day_of_year(): Represents the day position within a year (1-365 or 1-366 for leap years). The chronon is one day, cycling within a year. -
week_of_year(): Represents the week position within a year (1-52 or 1-53) using the ISO 8601 week numbering system. -
month_of_year(): Represents the month position within a year (1-12). The chronon is one month, cycling within a year.
Custom cyclical time representations
You can create custom cyclical time representations using cyclical_time()
with any of the supported time units (see calendar_gregorian and calendar_isoweek).
For example, to create a representation for day of the month:
day_of_month <- new_cyclical_time_fn( chronon = day(1L), cycle = month(1L), default_calendar = cal_gregorian )
See Also
cyclical_time() for creating cyclical time vectors,
new_cyclical_time_fn() for creating cyclical time helper functions
Examples
month_of_year(Sys.Date())
day_of_year(Sys.Date())
day_of_week(Sys.Date())
day_of_week(as.Date("2025-12-15") + 0:6)
Duration vectors
Description
duration() creates a vector of durations with a specified chronon.
Durations represent a fixed span of time measured in a given time granule
(e.g., 3 months, 5 days), without reference to a specific point in time.
Usage
duration(
data,
chronon = time_chronon(data),
discrete = NULL,
calendar = time_calendar(data)
)
Arguments
data |
A time vector of duration magnitudes, or an existing
|
chronon |
A time granule expression representing the chronon, evaluated
in the context of |
discrete |
Logical. If |
calendar |
Calendar system used to evaluate |
Value
A mixtime vector containing an mt_duration vector.
See Also
-
new_duration_fn()for creating reusable duration functions -
cal_gregorian, cal_isoweek for calendar systems
Examples
# A duration of 3 months
duration(3L, cal_gregorian$month(1L))
# A vector of durations in days
duration(1:7, cal_gregorian$day(1L))
# Convert a duration of 4 days into weeks
duration(days(4), cal_isoweek$week(1L), discrete = FALSE)
duration(days(4), cal_isoweek$week(1L), discrete = TRUE)
Duration helper functions
Description
Convenience functions for creating duration vectors of common time units.
Each function wraps new_duration_fn() for its respective chronon.
Usage
years(data, calendar = time_calendar(data), ...)
quarters(data, calendar = time_calendar(data), ...)
months(data, calendar = time_calendar(data), ...)
weeks(data, calendar = time_calendar(data), ...)
days(data, calendar = time_calendar(data), ...)
hours(data, calendar = time_calendar(data), ...)
minutes(data, calendar = time_calendar(data), ...)
seconds(data, calendar = time_calendar(data), ...)
milliseconds(data, calendar = time_calendar(data), ...)
Arguments
data |
A time vector of duration magnitudes, or an existing
|
calendar |
Calendar system used to evaluate |
... |
Additional arguments passed to the chronon (e.g. |
Value
A mixtime vector containing an mt_duration vector.
See Also
-
new_duration_fn()for creating custom duration functions -
duration()for creating duration vectors directly -
cal_gregorian, cal_isoweek for calendar systems
Examples
years(3L)
quarters(2L)
months(6L)
weeks(4L)
days(7L)
hours(12L)
minutes(30L)
seconds(45L)
milliseconds(500L)
Format mixtime vectors
Description
Formats a mixtime vector as a character vector, using a glue-style format
string of {lin(...)}/{cyc(...)} tokens tailored to the vector's chronon
and cycle. If format is omitted, a sensible default is derived
automatically. See vignette("time-format-strings") for the format string
syntax.
Usage
## S4 method for signature 'mt_time'
format(x, ..., attr = TRUE)
Arguments
x |
A mixtime vector. |
... |
Additional arguments for methods, including |
attr |
If |
Value
A character vector the same length as x.
Check if an object is a mixtime
Description
Tests whether x inherits from the mixtime class.
Usage
is_mixtime(x)
Arguments
x |
An object to test. |
Value
A scalar logical: TRUE if x is a mixtime vector, FALSE
otherwise.
See Also
as_mixtime() to coerce objects to mixtime,
mixtime() to construct a mixtime.
Examples
is_mixtime(Sys.Date())
is_mixtime(mixtime(Sys.Date()))
Check the time type of values
Description
Test whether elements of a mixtime vector are linear, cyclical, or durations.
Usage
time_is_linear(x, ...)
time_is_cyclical(x, ...)
time_is_duration(x, ...)
is_time_linear(x, ...)
is_time_cyclical(x, ...)
is_time_duration(x, ...)
Arguments
x |
A time object (typically a |
... |
Additional arguments for methods. |
Details
These helpers return a logical vector the same length as x identifying the
type of time represented by each element.
Value
A logical vector the same length as x.
Examples
t <- c(yearmonth(0), month_of_year(0), months(0L))
time_is_linear(t)
time_is_cyclical(t)
time_is_duration(t)
Describe a granule's label scheme
Description
Builds the function a linear_labels()/cyclical_labels() method is:
assign its result directly, e.g. method(cyclical_labels, list(granule, cycle)) <- label_scheme(...). Three levels, from plain to most irregular:
linear_labels() and cyclical_labels() are S7 generics returning a
granule's label scheme: a plain list describing how its internal position
renders as text and parses back (start, vocab, transform, width,
locale; see label_scheme()).
Usage
label_scheme(
start = 0L,
vocab = NULL,
transform = NULL,
width = NULL,
locale = NULL
)
linear_labels(granule, ...)
cyclical_labels(granule, cycle, ...)
Arguments
start |
Author-fixed. Raw index 0 displays as |
vocab |
|
transform |
|
width, locale |
Caller-overridable defaults for |
granule |
A time granule instance (e.g. |
... |
Unused; only present for S7 dispatch. |
cycle |
For |
Details
Plain numeric. No
vocab: labels arei + start, optionally zero-padded towidth. The default for most granules (minutes, seconds).Named, regular.
vocabsupplies the names (seevocab_table());startpositions raw index 0 in both the numeric and vocab-indexed rendering. Covers most named calendar units (months, weekdays).Named, irregular.
transformoverrides the plainstartshift with hand-writtenencode/decode, for cycles where raw index and name aren't a constant offset apart (e.g. a leap month splitting one name into two). See "Irregular cycles" below.
A scheme is only consulted for named (label = TRUE) rendering and its
inverse; numeric rendering is always the plain i + start shift (see
linear_labels_format()). Labels that aren't index-shaped at all (e.g.
"1BC") override the generics directly, documented in linear_labels()
instead.
linear_labels_format()/linear_labels_parse() (and their cyclical
counterparts) do the actual rendering/parsing, with the default method
looking up the scheme and applying it. A granule with labels that are
incompatible with label schemes (e.g. 2BC, 1BC, 1, 2, ...) registers a method
directly on those generics instead, skipping the scheme system. See
"Overriding the generics directly" below.
Value
A function function(granule, cycle) list(start =, vocab =, transform =, width =, locale =), assignable directly as a
linear_labels()/cyclical_labels() method. granule/cycle are only
used for dispatch: a scheme describes a granule class, not the instance
a method happens to be called with.
A plain list, as constructed by label_scheme().
Locale specific labels
vocab is a plain closure, not a shared registry, so two calendar
packages can't collide on it. To add locale support to an existing
granule, redefine the linear_labels()/cyclical_labels() method and
call the previous one for anything you're not changing: the normal S7
rule that the last method(...) <- wins. That needs a hand-written
wrapper rather than assigning label_scheme()'s result directly, since
overriding one field means fetching the old scheme and changing it:
scheme <- cyclical_labels(cal_gregorian$month(1L), cal_gregorian$year(1L))
method(cyclical_labels, list(cal_gregorian$month, cal_gregorian$year)) <-
function(granule, cycle) {
scheme$vocab <- function(type = NULL, locale = NULL) {
if (identical(locale %||% "en-GB", "fr-FR")) {
fr <- list(
wide = c("janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"),
abbreviated = c("janv.", "févr.", "mars", "avr.", "mai", "juin",
"juil.", "août", "sept.", "oct.", "nov.", "déc.")
)
return(if (is.null(type)) fr else fr[[type]])
}
scheme$vocab(type, locale)
}
scheme
}
Locale tags follow BCP 47 ("en-GB", "fr-FR"), like ICU, stringi and
clock. Type names follow CLDR's wide/abbreviated/narrow, so CLDR data
(e.g. stringi::stri_datetime_symbols()) works with vocab_table()
unchanged. Other type values are allowed too, e.g. "emoji" for lunar
phases, picked at render time via cyclical_labels_format()'s type
argument.
Irregular cycles
at (in transform's encode/decode, and in
cyclical_labels_format()/cyclical_labels_parse()) is the coarser
granule instance's raw position, not epoch-shifted, with n = 1. It
follows the same convention as chronon_cardinality(). It lets
transform pick the right name when that name depends on which cycle
instance a raw index falls in, e.g. the Hebrew calendar's leap year
splitting "Adar" into "Adar I"/"Adar II":
month_names <- c("Tishrei", "Cheshvan", "Kislev", "Tevet", "Shevat",
"Adar", "Adar I", "Adar II",
"Nisan", "Iyar", "Sivan", "Tammuz", "Av", "Elul")
method(cyclical_labels, list(cal_hebrew$month, cal_hebrew$year)) <- label_scheme(
start = 1L,
vocab = vocab_table(`en-GB` = list(wide = month_names, abbreviated = month_names)),
transform = list(
encode = function(i, at) {
leap <- is_hebrew_leap_year(at)
if (i <= 4L) return(i + 1L)
if (!leap) return(if (i == 5L) 6L else i + 3L)
if (i == 5L) return(7L)
if (i == 6L) return(8L)
i + 2L
},
decode = function(d, at) {
leap <- is_hebrew_leap_year(at)
if (d <= 5L) return(d - 1L)
if (!leap) {
if (d == 6L) return(5L)
if (d %in% c(7L, 8L)) cli::cli_abort("'Adar I'/'Adar II' are not valid outside a leap year.")
return(d - 3L)
}
if (d == 6L) cli::cli_abort("'Adar' is ambiguous in a leap year, use 'Adar I' or 'Adar II'.")
if (d == 7L) return(5L)
if (d == 8L) return(6L)
d - 2L
}
)
)
The aborts in decode() matter: without them, "Adar II" typed in a
common year would fall through to the same offset as plain "Adar" and
silently parse to the wrong month. Only the label layer, which knows
both the text and at, can catch that. transform's leap predicate must
also be the same one chronon_cardinality() uses for this pair; put it
in one shared helper.
Overriding the format and parsing methods
linear_labels_format()/linear_labels_parse() are ordinary S7
generics with a default method, not the only place formatting logic can
live. So escaping the scheme system for one granule is just registering
a method directly:
method(linear_labels_format, cal_gregorian$year) <- function(granule, i, ...) {
ifelse(i <= 0L, paste0(-i + 1L, "BC"), i)
}
method(linear_labels_parse, cal_gregorian$year) <- function(granule, ...) {
list(
pattern = "\\d+(?:BC)?",
decode = function(text, at = NULL) {
bc <- grepl("BC$", text)
n <- as.integer(sub("BC$", "", text))
ifelse(bc, 1L - n, n) - chronon_epoch(granule)
}
)
}
decode() needs - chronon_epoch(granule) because this method bypasses
the default, which normally does that step (see linear_labels_format()'s
"Epoch shift" section).
The ... on _format() is not just style: format() forwards whatever
component_helpers' lin()/cyc() were called with (label,
abbreviate, type, width, locale, ...) as named arguments. A
method without ... errors with "unused argument" as soon as a caller
passes something it doesn't declare.
Registering only linear_labels_format() is fine: that's the same "no
parsing yet" state a fresh granule starts in. But registering it without
linear_labels_parse() leaves parsing silently wrong instead of just
missing: text like "1BC" falls through to whatever the granule's
scheme says, usually plain numeric decoding, which doesn't understand
"BC" at all.
See Also
linear_labels()/cyclical_labels(), the generics a scheme is
returned from; vocab_table() for the common hand-listed name table
case.
label_scheme() for the fields a method returns;
linear_labels_format()/cyclical_labels_format() for the generics
that interpret it; vocab_table() for the common hand-listed name
table case.
Examples
# A scheme for months of the year, using R's localised month names.
S7::method(cyclical_labels, list(cal_gregorian$month, cal_gregorian$year)) <- label_scheme(
start = 1L, width = 2L,
vocab = vocab_table(`en-GB` = list(wide = month.name, abbreviated = month.abb))
)
Render and parse a granule's labels
Description
The generics turning a granule's internal position into display text
(linear_labels_format() for a non-repeating position, e.g. the year;
cyclical_labels_format() for a position within a larger cycle, e.g. the
month within the year) and back (linear_labels_parse()/
cyclical_labels_parse()).
Usage
linear_labels_format(granule, ...)
cyclical_labels_format(granule, cycle, ...)
linear_labels_parse(granule, ...)
cyclical_labels_parse(granule, cycle, ...)
Arguments
granule |
A time granule object representing the granule (e.g.
|
... |
Passed on to the method. The default method (see below) takes:
|
cycle |
A time granule object representing the cycle (e.g.
|
Details
Each has one default method (on the base mt_unit class) that looks up
the granule's scheme via linear_labels()/cyclical_labels() and
applies it (see label_scheme() for the fields). Calendar authors
usually declare a scheme instead of writing a method here directly.
Writing one directly overrides the generics for labels that aren't
index-shaped at all, see linear_labels()'s "Overriding the generics
directly" section.
Value
Character vector of labels for the time point.
Epoch shift
linear_labels_format()'s i arrives already epoch-shifted for display
(chronon_parts() adds chronon_epoch() before calling it, e.g. a
Gregorian year's i is 2024, not 54). The default
linear_labels_parse() method shifts decode()'s output back, by
subtracting chronon_epoch() after the scheme's own decode runs. A
hand-written override method skips this and must do the same
subtraction itself if the granule has a non-zero epoch; see the example
in linear_labels().
See Also
linear_labels()/cyclical_labels() for the authoring
interface these generics' default methods interpret.
Examples
# Labels for years on a linear axis
with(cal_gregorian, linear_labels_format(year(1L), 2020:2025))
# Labels for months in a year
with(cal_gregorian, cyclical_labels_format(month(1L), year(1L), 0:11))
Linear time points
Description
linear_time() creates a vector of linear time points with a specified
chronon (smallest time granule). This function is useful for creating custom
time representations that aren't covered by the convenience functions like
yearmonth() or yearweek().
Usage
linear_time(
data,
chronon = time_chronon(data),
discrete = TRUE,
calendar = time_calendar(data)
)
Arguments
data |
Input data to convert to linear time. Can be:
|
chronon |
A time granule expression representing the chronon (smallest
indivisible time granule), evaluated in the context of |
discrete |
Logical. If |
calendar |
Calendar system used to evaluate |
Value
A mixtime time vector containing an mt_linear vector.
See Also
-
new_linear_time_fn()for creating reusable linear time functions -
yearmonth(),yearquarter(),year()for Gregorian time representations -
yearweek()for ISO 8601 week-based time -
cal_gregorian, cal_isoweek for calendar systems
Examples
# Hourly time
linear_time(
Sys.time(),
chronon = hour(1L)
)
# Monthly time
linear_time(
Sys.Date(),
chronon = month(1L)
)
# Discrete vs continuous time
linear_time(Sys.time(), chronon = day(1L), discrete = TRUE)
linear_time(Sys.time(), chronon = day(1L), discrete = FALSE)
# ISO week calendar with week-day structure
linear_time(
Sys.Date(),
chronon = day(1L),
calendar = cal_isoweek
)
Linear time helper functions
Description
Convenience functions for creating common linear time representations. These functions work with different calendar systems and adapt based on the input data's calendar.
Usage
year(data, discrete = TRUE, calendar = time_calendar(data), ...)
yearquarter(data, discrete = TRUE, calendar = time_calendar(data), ...)
yearmonth(data, discrete = TRUE, calendar = time_calendar(data), ...)
yearweek(data, discrete = TRUE, calendar = time_calendar(data), ...)
date(data, discrete = TRUE, calendar = time_calendar(data), ...)
datetime(data, discrete = TRUE, calendar = time_calendar(data), ...)
Arguments
data |
A vector of time points (e.g. base::Date, base::POSIXt) |
discrete |
If |
calendar |
A calendar used to evaluate the time units. Defaults to the calendar of the input data. Common options include cal_gregorian and cal_isoweek. |
... |
Additional arguments for |
Details
These functions create linear time representations with different chronons and granules:
-
year(): Represents time in whole years. The chronon is one year. -
yearquarter(): Represents time in quarters, grouped by year. The chronon is one quarter, with years as the granule. -
yearmonth(): Represents time in months, grouped by year. The chronon is one month, with years as the granule. -
yearweek(): Represents time in weeks, grouped by year. The chronon is one week, with years as the granule. Defaults to ISO 8601 week calendar.
Value
A mixtime time vector containing an mt_linear vector with chronons matching the function used.
Calendar flexibility
These functions adapt to the calendar system of the input data. For example:
-
year(date("2025-12-29"))returns a Gregorian year -
year(yearweek(date("2025-12-29")))returns an ISO week-based year
You can also explicitly specify a calendar using the calendar argument:
year(date("2025-12-29"), calendar = cal_isoweek)
Custom linear time representations
For more complex time structures, use linear_time() or new_linear_time_fn()
to create custom representations with any combination of chronons and granules.
See Also
-
linear_time()for creating custom linear time representations -
new_linear_time_fn()for creating reusable linear time functions -
cal_gregorian, cal_isoweek for calendar systems
Examples
# Gregorian year
year(Sys.Date())
year(Sys.Date(), discrete = FALSE)
# ISO week-based year
year(yearweek(Sys.Date()))
# Year-quarter
yearquarter(Sys.Date())
yearquarter(Sys.Date(), discrete = FALSE)
# Year-month
yearmonth(Sys.Date())
yearmonth(Sys.Date(), discrete = FALSE)
# Year-week (ISO 8601)
yearweek(Sys.Date())
yearweek(0:52)
Create a mixtime vector
Description
A mixtime is a vector which describes a point in time. It uses a calendar definition to translate a vector of numbers into a point in time.
Usage
mixtime(
data,
chronon = time_chronon(data),
cycle = time_cycle(data),
discrete = TRUE
)
Arguments
data |
A vector of time values. This can be a character vector (e.g. "2024-01-01"), a numeric vector (e.g. seconds since epoch), or a time class (e.g. Date, POSIXct, yearmonth, etc.). |
chronon |
A time granule object representing the smallest indivisible time granule (chronon) for the mixtime. This is used to interpret the numeric values in |
cycle |
An optional time granule object representing the cycle for cyclical time. This is used to define the repeating cycle for cyclical time representations (e.g. day-of-week, month-of-year). If not provided, the mixtime will be treated as linear time. |
discrete |
A logical indicating whether the time values should be treated as discrete (integer) or continuous (fractional). This affects how numeric values are interpreted and how time arithmetic is performed. The default is |
Value
A mixtime object representing the time values in data according to the specified chronon and cycle.
Examples
# Create a mixtime for today
mixtime(Sys.Date())
# Create a mixtime for the current date and time
mixtime(Sys.time())
# Convert time from tsibble classes to mixtime
mixtime(tsibble::yearmonth("2024 Jan"))
# Create a mixtime for the time of day (cyclical time)
mixtime(Sys.time(), cycle = cal_gregorian$day(1L))
# Specify a timezone for the chronon
mixtime(Sys.time(), chronon = cal_gregorian$second(1L, tz = Sys.timezone()))
mixtime(Sys.time(), chronon = cal_gregorian$second(1L, tz = "Pacific/Honolulu"))
mixtime(Sys.time(), chronon = cal_gregorian$second(1L, tz = "Australia/Melbourne"))
# Dates (and all granularities) can have timezones
mixtime(Sys.time(), chronon = cal_gregorian$day(1L, tz = Sys.timezone()))
mixtime(Sys.time(), chronon = cal_gregorian$day(1L, tz = "Pacific/Honolulu"))
mixtime(Sys.time(), chronon = cal_gregorian$day(1L, tz = "Australia/Melbourne"))
# Continuous time tracks progress within the chronon
mixtime(Sys.time(), chronon = cal_gregorian$day(1L, tz = Sys.timezone()), discrete = FALSE)
# Mixtime can combine different granularities and timezones in a vector
now <- Sys.time()
c(
# Datetime (second chronon) in UTC
mixtime(now),
# Date (minute chronon) in local timezone
mixtime(now, chronon = cal_gregorian$minute(1L, tz = Sys.timezone())),
# Month (month chronon) in UTC
mixtime(now, chronon = cal_gregorian$month(1L))
)
Extract locations from an object
Description
Generic function to extract the location from objects that have location information.
Usage
loc_latitude(x, ...)
loc_longitude(x, ...)
loc_altitude(x, ...)
Arguments
x |
An object with location information. |
... |
Additional arguments passed to methods. |
Value
A numeric value representing the location (e.g., longitude, latitude, etc.).
Examples
t <- linear_time(
1:3,
cal_time_solar$day(1L, lat = -37.8136, lon = 144.9631)
)
loc_longitude(t)
loc_latitude(t)
loc_altitude(t)
Comparison operators for cyclical time (mt_cyclical)
Description
A cyclical time value stores an absolute chronon count but means a position
within its cycle (e.g. day_of_week() means a weekday, not a particular
Wednesday). Comparison therefore reduces both operands to their position
within the cycle - the same reduction format() displays - and compares
those:
-
day_of_week(date("2020-01-15")) == day_of_week(date("2020-01-22"))isTRUE, since both are a Wednesday. -
day_of_year(date("2020-01-15")) == day_of_year(date("2021-01-15"))isTRUE, since both are the 15th day of their year.
Both operands must share a cycle: a cycle is a modulus rather than a unit,
so there is no meaningful common cycle between (say) a weekday and a
day-of-year, and comparing them is an error. Differing chronons within a
shared cycle are reconciled as they are for mt_linear:
both positions are expressed in the finest common chronon, and a discrete
value spans the closed interval of its chronon, so
-
a == biffstart(a) == start(b)andend(a) == end(b) -
a < biffend(a) < start(b),a > biffstart(a) > end(b) -
a <= biffend(a) <= end(b),a >= biffstart(a) >= start(b)
As for mt_linear, this is not a total order when chronons differ. Ordering
follows the position within the cycle (so Mon < Wed); the cycle's wrap-around
is not treated as circular.
Usage
## S4 method for signature 'mt_cyclical'
e1 == e2
## S4 method for signature 'mt_cyclical'
e1 != e2
## S4 method for signature 'mt_cyclical'
e1 < e2
## S4 method for signature 'mt_cyclical'
e1 <= e2
## S4 method for signature 'mt_cyclical'
e1 > e2
## S4 method for signature 'mt_cyclical'
e1 >= e2
Arguments
e1, e2 |
|
Value
A logical vector.
Comparison operators for durations (mt_duration)
Description
A duration is a scalar magnitude of time measured in a given chronon (e.g.
days(3)), with no reference to a point in time. Comparing two durations is
therefore a plain magnitude comparison, once both operands have been
expressed in a common chronon:
-
a == biff the two magnitudes are equal in their common chronon -
a < b,a <= b,a > b,a >= bcompare the magnitudes directly
Unlike mt_linear comparison there is no interval/span to consider, so this
is a total order. When both operands already share a chronon the magnitudes
are compared as-is; otherwise both are scaled to their finest common chronon
(the same scaling used when combining durations arithmetically, see
duration_combine()).
Usage
## S4 method for signature 'mt_duration'
e1 == e2
## S4 method for signature 'mt_duration'
e1 != e2
## S4 method for signature 'mt_duration'
e1 < e2
## S4 method for signature 'mt_duration'
e1 <= e2
## S4 method for signature 'mt_duration'
e1 > e2
## S4 method for signature 'mt_duration'
e1 >= e2
Arguments
e1, e2 |
|
Value
A logical vector.
Comparison operators for linear time (mt_linear)
Description
Discrete linear time values represent a closed interval spanning their
chronon (e.g. year(2020) spans every instant from the start of 2020 to
the end of 2020), while continuous linear time values represent a single
instant. Comparing two mt_linear vectors therefore compares the
start/end instants of the (possibly zero-width) interval each value
represents:
-
a == biffstart(a) == start(b)andend(a) == end(b) -
a < biffend(a) < start(b) -
a > biffstart(a) > end(b) -
a <= biffend(a) <= end(b)(right-bound comparison) -
a >= biffstart(a) >= start(b)(left-bound comparison)
This is not a total order: <=/>= are endpoint comparisons, not
shorthand for (< or ==)/(> or ==), so it is possible for none of
==, <, > to hold between two values.
If both operands are continuous (fractional chronons), or share an identical chronon, the comparison simplifies to a direct numeric comparison, since there is no interval to consider.
Usage
## S4 method for signature 'mt_linear'
e1 == e2
## S4 method for signature 'mt_linear'
e1 != e2
## S4 method for signature 'mt_linear'
e1 < e2
## S4 method for signature 'mt_linear'
e1 <= e2
## S4 method for signature 'mt_linear'
e1 > e2
## S4 method for signature 'mt_linear'
e1 >= e2
Arguments
e1, e2 |
|
Value
A logical vector.
Time vector classes
Description
The mt_time family are the S7 vector classes that store time points as a
numeric count of chronons. mt_time is the (internal) base class carrying
the chronon property; the common modes of time are:
-
mt_linear- linear time points, typically produced withlinear_time(). -
mt_cyclical- cyclical time points with additionalcyclegranule, typically produced withcyclical_time(). -
mt_duration- time durations, typically produced withduration().
The underlying data can be either integer (discrete time) or double
(continuous time). The chronon (and, for mt_cyclical, the cycle) are
time granules, the result from a mt_unit object.
Usage
mt_linear(.data = integer(), chronon = mt_unit(1L))
mt_duration(.data = integer(), chronon = mt_unit(1L))
mt_cyclical(.data = integer(), chronon = mt_unit(1L), cycle = mt_unit(1L))
Arguments
.data |
A numeric vector of chronon counts (integer or double). |
chronon, cycle |
Time granules (mt_unit objects) giving the unit of the
chronon counts and, for |
Value
An S7 class object (used for method dispatch), or a time vector when called as a constructor.
See Also
mt_linear(), mt_duration(), and mt_cyclical() to construct
time vectors, and mt_unit for the granule type stored in chronon/cycle.
Base S7 class for creating new time units
Description
This class is the primitive class for time units, and should
be extended from when creating new time units. A new class
is typically created with S7 using:
S7::new_class("tu_***", parent = mt_tz_unit)
Usage
mt_unit(n = 1L)
mt_loc_unit(n = 1L, lat = naive_loc, lon = naive_loc, alt = naive(0))
mt_tz_unit(n = 1L, tz = naive_tz)
Arguments
n |
The step size of time granule. For example, |
lat |
Numeric. Latitude in decimal degrees. Range: -90 to 90.
Default: naive location (astronomical calculations require |
lon |
Numeric. Longitude in decimal degrees. Range: -180 to 180.
Default: naive location (astronomical calculations require |
alt |
Numeric. Altitude in meters above sea level. Default: 0 (sea level). |
tz |
The timezone name for the unit (valid units can be found with |
Details
Time units are the building blocks of calendars in mixtime. Each unit
represents a specific temporal component (e.g., day, month, year) and
can be combined using new_calendar() to create a calendar system.
When creating custom calendars, define time unit classes that inherit
from either mt_unit (for standard units) or mt_tz_unit (for
timezone-aware units), then pass them as named arguments to
new_calendar(). The calendar will use these names to create
constructor functions accessible via $ notation (e.g., calendar$day(1L)).
Value
A time granule object of class mt_unit
Calendar Algebra Methods
Time units enable calendar arithmetic through key generic methods that should be implemented for custom time units:
-
chronon_cardinality_fixed(x, y)- Returns the number of unitxgranules that fit within one unitygranule, for relationships that are a constant, context-independent number (e.g., 7 days per week, 24 hours per day). Prefer this overchronon_cardinality()whenever the relationship does not depend onat, since it is also used to determine which relationships are safe to use forchronon_divmod()'s graph traversal. -
chronon_cardinality(x, y, at)- Returns the number ofxgranule that fit within oneygranule. This is variable based onat(e.g., 28-31 days per month). Only implement this directly (rather thanchronon_cardinality_fixed()) when the relationship genuinely depends onat, and pair it with a directchronon_divmod()method so that the relationship remains reachable during graph traversal. -
chronon_divmod(x, from, to)- Converts time pointxfrom granules offromto granules ofto, returning a list withdiv(the quotient) andmod. This enables conversions between granules that have variable cardinality (e.g., the date 2020-03-23 to the month 2020-03). All conversions should be based on chronons since epoch (1970-01-01), in the UTC time zone.
These methods work together to enable mixtime to perform calendar-aware arithmetic, understanding that months have variable lengths and handling timezone-aware conversions.
See Also
new_calendar() for creating calendars from time units
Examples
# Create a timezone-aware unit class
# Use these units to create a calendar
my_calendar <- new_calendar(
day = S7::new_class("tu_my_day", parent = mt_unit),
month = S7::new_class("tu_my_month", parent = mt_tz_unit),
class = "my_calendar"
)
# Access unit constructors from the calendar
my_calendar$day(1L)
my_calendar$month(3L, tz = "America/New_York")
Create a new calendar
Description
Define a new calendar as a collection of time units. Calendars are the foundation for representing dates and times in terms of human-readable components like years, months, days, hours, minutes, and seconds. Each calendar is defined by specifying the time units it contains, which determine how time values can be interpreted and manipulated.
Usage
new_calendar(..., inherit = NULL, class = character())
Arguments
... |
Named time unit class definitions. Each argument should be a
time unit class (typically created with |
inherit |
Optional calendar to inherit time units from. Units
defined in |
class |
Character vector of additional classes for the calendar object. |
Details
Time units are typically S7 class definitions that inherit from mt_unit
for standard units, mt_tz_unit for timezone-aware units (civil time), or
mt_loc_unit for location-aware units (astronomical time). The calendar
object provides a namespace for accessing these unit constructors and
defines the relationships between them for calendar arithmetic.
Value
A calendar object of class c(class, "mt_calendar"), consisting of a
named list containing the specified time unit classes.
See Also
linear_time(), cyclical_time()
Examples
# Create a simple calendar with year and month units
# (inheriting from civil time units for day, hour, minute, second, ...)
cal_simple <- new_calendar(
year = new_time_unit("tu_year", parent = mt_tz_unit),
month = new_time_unit("tu_month", parent = mt_tz_unit),
inherit = cal_time_civil,
class = "cal_simple"
)
# Create time granules from the calendar
cal_simple$year(1L)
cal_simple$month(1L)
Cyclical time function factory
Description
new_cyclical_time_fn() creates a cyclical time function for a specified
chronon and cycle. The cycle is the larger time granule that defines the time
period over which the chronon loops (e.g., a week). The chronon is the smaller
time granule that iterates within each cycle (e.g., a day). Combined, these two
granules form a cyclical time relationship (e.g., day of the week).
Usage
new_cyclical_time_fn(chronon, cycle, default_calendar = cal_gregorian)
Arguments
chronon |
A time granule object representing the chronon (e.g., |
cycle |
A time granule object representing the cycle (e.g., |
default_calendar |
A default calendar used to find the time units for
conversion if they don't exist in the calendar of the input data (e.g., |
Value
A function used to create cyclical time points with a specific chronon and cycle.
Examples
day_of_week <- new_cyclical_time_fn(day(1L), week(1L), default_calendar = cal_isoweek)
day_of_week(Sys.Date())
month_of_year <- new_cyclical_time_fn(month(1L), year(1L))
month_of_year(Sys.Date())
Duration function factory
Description
new_duration_fn() creates a duration function for a specified chronon. A
chronon is the smallest indivisible time unit (e.g., days, months) that
defines what the numeric magnitudes in the resulting duration vector
represent.
Usage
new_duration_fn(chronon, default_calendar = cal_gregorian)
Arguments
chronon |
A bare call for a time unit object representing the chronon
(e.g., |
default_calendar |
A default calendar used to resolve the time units
if they don't exist in the calendar of the input data (e.g.,
|
Value
A function used to create duration vectors with a specific chronon. The returned function accepts:
dataA numeric vector of duration magnitudes.
calendarA calendar system used to evaluate
chronon. Defaults totime_calendar(data)....Additional arguments passed to the chronon (e.g.,
tzfor timezones).
See Also
-
duration()for creating duration vectors directly -
cal_gregorian, cal_isoweek for calendar systems
Examples
# Create a months duration function
months <- new_duration_fn(month(1L), default_calendar = cal_gregorian)
months(1:6)
# Create a days duration function
days <- new_duration_fn(day(1L), default_calendar = cal_gregorian)
days(1:7)
Linear time function factory
Description
new_linear_time_fn() creates a linear time function for a specified
chronon. A chronon is the smallest indivisible time granule (e.g., days,
hours).
Usage
new_linear_time_fn(chronon, default_calendar = cal_gregorian)
Arguments
chronon |
A bare call for a time granule object representing the chronon
(e.g., |
default_calendar |
A default calendar used to find the time units for
conversion if they don't exist in the calendar of the input data (e.g.,
|
Value
A function used to create linear time points with a specific chronon.
Examples
# Linear time with 1 month granules as the chronon
ym <- new_linear_time_fn(month(1L))
ym(Sys.Date())
# Linear time with 1 day granules as the chronon
yd <- new_linear_time_fn(day(1L))
yd(Sys.Date())
# Linear time with 1 week granules as the chronon, using the ISO week calendar
yw <- new_linear_time_fn(week(1L), default_calendar = cal_isoweek)
yw(Sys.Date())
# Linear time with 1 hour granules as the chronon
ymd_h <- new_linear_time_fn(hour(1L))
ymd_h(Sys.time())
Constructor for mixtime vectors
Description
Creates a mixtime vector, which can contain time points of different
granularities (e.g. monthly and quarterly) in a single vector via vecvec.
Usage
new_mixtime(x = mt_linear())
Arguments
x |
A mixtime time vector (created with |
Value
A mixtime object, which allows mixed-type time vectors to coexist in a single vector.
Constructor for mixtime time vectors
Description
new_time() was the low-level constructor for mt_time vectors. It has been
deprecated in favour of calling the concrete time class constructors directly:
mt_linear() for linear time, mt_duration() for durations, and
mt_cyclical() for cyclical time.
Creates a mixtime time vector at a specific time point, with a specified
chronon and optional cycle. The chronon defines the smallest indivisible
time granule for the time vector, while the cycle allows for cyclical time
representations (e.g. day-of-week, month-of-year).
Usage
new_time(x = integer(), chronon = mt_unit(1L), cycle = NULL, class = NULL)
Arguments
x |
A numeric vector of time points, integers for discrete time or doubles for continuous time. |
chronon |
A time granule object representing the smallest indivisible time
granule (chronon) for the time vector (e.g. |
cycle |
An optional time granule object representing the cycle for cyclical
time (e.g. |
class |
An optional character vector of additional S3 classes to assign
to the resulting time vector. This allows for further subclassing of
|
Value
A mt_time vector representing the time points in x according to
the specified chronon and cycle.
Examples
# Create a continuous mixtime time vector for today
new_time(
as.double(Sys.Date()),
chronon = cal_gregorian$day(1L, tz = Sys.timezone()),
class = "mt_linear"
)
# Create a discrete mixtime time vector for the current date and time
new_time(
as.integer(Sys.time()),
chronon = cal_gregorian$second(1L, tz = Sys.timezone()),
class = "mt_linear"
)
# Create a discrete mixtime time vector for the time of day (cyclical time)
new_time(
as.integer(Sys.time()),
chronon = cal_gregorian$second(1L, tz = Sys.timezone()),
cycle = cal_gregorian$day(1L, tz = Sys.timezone()),
class = "mt_cyclical"
)
Create a new time unit class
Description
Define a new S7 class representing a time unit for use in a mixtime calendar.
Time units are the building blocks of calendars: each unit represents a
specific temporal component (e.g., day, month, year) and carries a step size
n. Units are combined via new_calendar() to form a complete calendar
system.
Usage
new_time_unit(
name,
parent = mt_unit,
package = topNamespaceName(parent.frame()),
properties = list(),
abstract = FALSE,
constructor = NULL,
validator = NULL
)
Arguments
name |
A string naming the new S7 class (e.g., |
parent |
The parent S7 class. Should be one of |
package |
A string giving the package name that owns the class. Defaults to the name of the calling namespace, so typically does not need to be set explicitly. |
properties |
A named list of additional |
abstract |
Logical. If |
constructor |
A function to use as the class constructor, or |
validator |
A function of one argument ( |
Details
Choose the parent class based on the type of time the unit represents:
-
mt_unit— abstract or calendar-only time (no timezone or location context; e.g., Gregorian year or ISO week). -
mt_tz_unit— civil time with a timezone (e.g., a clock hour that needstzto resolve wall-clock ambiguity). -
mt_loc_unit— astronomical time with a geographic location (e.g., a solar day tied to observer longitude/latitude).
Value
An S7 class object, as returned by S7::new_class().
See Also
-
mt_unit,mt_tz_unit,mt_loc_unitfor the base classes to inherit from. -
new_calendar()for assembling time units into a calendar. -
S7::new_class()for the underlying S7 class constructor.
Examples
# An abstract unit with no properties
tu_my_seq <- new_time_unit("tu_my_seq", parent = mt_unit)
# A civil-time unit with an extra property
tu_my_quarter <- new_time_unit(
"tu_my_quarter",
parent = mt_tz_unit,
properties = list(
fiscal = S7::new_property(S7::class_logical, default = FALSE)
)
)
Candidate format strings for parsing time
Description
Combines one or more format strings into a character vector for use as
the format argument of time_parse(). When multiple format strings are
given, time_parse() tries each in turn and keeps whichever parses the
most values, so parse_format() is the usual way to build up a set of
candidates to try (it's also how chronon_parse_linear()/
chronon_parse_cyclical() methods build theirs). It can optionally mark
its candidates as using regex syntax rather than literal text; see the
regex argument below.
Usage
parse_format(..., regex = FALSE)
Arguments
... |
Format strings, as for the |
regex |
Whether the literal (non-token) text in |
Value
A character vector of format strings suitable for time_parse(),
with a "regex" attribute for the regex argument the parser.
See Also
time_parse() for using the result as format,
chronon_parse_linear()/chronon_parse_cyclical() for calendar-specific
candidates built this way.
Examples
parse_format("{lin(year)}-{cyc(month, year)}-{cyc(day, month)}")
# Multiple candidates are tried in turn, keeping whichever parses most values
parse_format(
"{lin(year)}-{cyc(month, year)}-{cyc(day, month)}",
"{lin(year)}/{cyc(month, year)}/{cyc(day, month)}"
)
# regex = TRUE treats the surrounding text as regular expression syntax
parse_format(
"{lin(year)}[/-]{cyc(month, year)}[/-]{cyc(day, month)}",
regex = TRUE
)
Generate sequences of mixtime values
Description
Create regular sequences of time values. This method handles both linear time sequences (dates, date-times) and cyclical time sequences (day of week, month of year).
Usage
## S3 method for class ''mixtime::mixtime''
seq(...)
## S3 method for class ''mixtime::mt_time''
seq(
from,
to,
by,
length.out = NULL,
along.with = NULL,
on_invalid = c("nearest", "overflow"),
...
)
Arguments
... |
Additional arguments passed to the underlying sequence method. |
from |
Starting value of the sequence. |
to |
End value of the sequence (if provided). |
by |
Increment of the sequence. Can be:
|
length.out |
Desired length of the sequence (alternative to |
along.with |
Take the length from this argument (alternative to |
on_invalid |
How to handle time points that overflow the cycle when
using a
This is relevant when the starting time point has an offset that doesn't
exist in all cycles. For example, starting on day 31 with If not explicitly specified and overflow occurs, a warning is issued with
the default |
Details
For linear time types (Date, POSIXct, yearmonth, etc.), sequences progress forward or backward in time. For cyclical time types (month_of_year, day_of_week, etc.), sequences wrap around cyclically.
Value
A mixtime vector containing the sequence.
Examples
# Linear time sequences with integer by
seq(yearmonth("2020 Jan"), yearmonth("2020 Dec"))
seq(yearquarter("2020 Q1"), length.out = 5, by = 3)
# Linear time sequences with string intervals
seq(date("2020-01-01"), date("2020-12-31"), by = "1 month")
seq(yearmonth("2020 Jan"), yearmonth("2025 Jan"), by = "1 year")
seq(date("2020-01-01"), length.out = 10, by = "2 weeks")
# Linear time sequences incrementing by time granules
seq(yearmonth("2020 Jan"), yearmonth(("2020 Dec")), by = cal_gregorian$month(2L))
seq(date("2020-01-01"), length.out = 5, by = cal_gregorian$year(1L))
seq(date("2020-01-01"), date("2020-01-31"), by = cal_gregorian$day(7L))
# Handling invalid dates with on_invalid
seq(date("2020-01-31"), length.out = 3, by = "1 month") # warns, uses nearest
seq(date("2020-01-31"), length.out = 3, by = "1 month", on_invalid = "nearest")
seq(date("2020-01-31"), length.out = 3, by = "1 month", on_invalid = "overflow")
# Cyclical time sequences
seq(month_of_year(0L), month_of_year(11L))
seq(day_of_week(0L), day_of_week(6L), by = 1)
Obtain the calendar of a time object
Description
This S7 generic function extracts the calendar system from a time object. The calendar defines the collection of time units (years, months, days, etc.) used to interpret the time representation.
Usage
time_calendar(x, ...)
Arguments
x |
A time object (e.g., base::Date, base::POSIXct, |
... |
Additional arguments for methods. |
Value
A calendar object (e.g., cal_gregorian, cal_isoweek)
Examples
# The calendar of a Date object is the Gregorian calendar
time_calendar(Sys.Date())
# The calendar of a POSIXct object is also Gregorian
time_calendar(Sys.time())
# The calendar of a yearweek object is the ISO week calendar
time_calendar(yearweek(Sys.Date()))
# A mixed time object returns a list of calendars
time_calendar(c(yearmonth(Sys.Date()), Sys.Date()))
Obtain the chronon of a time object
Description
This S7 generic function extracts the chronon (the smallest time granule) from a time object, such as continuous time or cyclical time representations.
Usage
time_chronon(x, ...)
Arguments
x |
A time object (e.g., base::Date, base::POSIXct, |
... |
Additional arguments for methods. |
Value
A time duration() vector representing the chronon of each
value (e.g., days(1L)).
Examples
# The chronon of a Date object is 1 day
time_chronon(Sys.Date())
# The chronon of a POSIXct object is 1 second
time_chronon(Sys.time())
# The chronon of a continuous time year and month is 1 month
time_chronon(yearmonth(Sys.Date()))
# The common chronon of a mixed time object is the finest chronon
time_chronon(c(yearmonth(Sys.Date()), Sys.Date()))
Extract linear and cyclical time components
Description
time_components() decomposes a time vector into its constituent parts using
dplyr::mutate()-like semantics. Each named expression is built from the
lin() and cyc() helpers (the same vocabulary used in format() strings)
and produces a component time vector:
Usage
time_components(x, ..., calendar = time_calendar(x))
Arguments
x |
A |
... |
Named expressions using |
calendar |
Calendar system used to resolve granule names, overlaid on the
calendar of |
Details
-
lin(<granule>)extracts a linear component (a non-repeating count, e.g. the year), returning a linear time vector. -
cyc(<granule>, <cycle>)extracts a cyclical component (a repeating position within a larger cycle, e.g. the month within the year), returning a cyclical time vector.
All requested components are computed together in a single decomposition of
the underlying time vector (via chronon_parts()), reusing the shared
recursive chronon_divmod() results rather than converting each component
independently.
Value
A data frame with one column per requested component. lin() columns
are linear (mt_linear) time vectors and cyc() columns are cyclical
(mt_cyclical) time vectors.
See Also
lin() and cyc() for the component helpers, linear_time() and
cyclical_time() for constructing individual component vectors, and
format() for the string counterpart of this interface.
Examples
t <- yearmonth(as.Date("2026-02-14") + c(0, 40, 400))
# Extract the year (linear) and month-of-year (cyclical)
time_components(t, yr = lin(year), mth = cyc(month, year))
# Components can be named automatically from the expression
time_components(as.Date("2025-12-15") + 0:3, cyc(day, cal_isoweek$week))
Compose a linear time vector from linear and cyclical components
Description
time_compose() is the inverse of time_components(): given a set of
lin()/cyc() components it reconstructs the corresponding time points.
Each component is either a two-sided formula pairing a spec with its value,
or an already-tagged linear/cyclical time vector (e.g. produced by
linear_time(), cyclical_time(), or a time_components() column).
Usage
time_compose(..., discrete = TRUE, calendar = cal_gregorian)
Arguments
... |
Components used to build the time point. Each element is either: |
discrete |
Logical. If |
calendar |
Calendar used to resolve bare granule names in |
Details
A lin() component (the anchor), when supplied, fixes the absolute
position at some granule (e.g. the year). Every other component must be
cyc(), chaining without gaps or branches from the anchor down to the
target chronon: each cycle must equal another component's chronon exactly.
With no lin() anchor, every component must be cyc(), chained the same
way but rooted at whichever component's cycle isn't itself another
component's chronon. The result is cyclical time tagged with that root's
cycle: cyc(month, year) ~ 3 alone matches month_of_year() for any
March; chaining cyc(day, month) ~ 15 onto it collapses to one (day,
year) pair, day-of-year 74, matching day_of_year() for 15 March.
Values of linear and cyclical components are specified on the right-hand-side
of the formula. A lin() value is the real-world count (e.g. the literal
year 1980); a cyc() value is the 1-indexed position within the cycle
(e.g. cyc(month, year) ~ 3 is the 3rd month, March), matching everyday
counting rather than the raw 0-indexed position time_components() uses
internally.
Value
A mixtime time vector, at the finest chronon reached by the
chain (or the root's own chronon, if only one component is given).
Linear with a lin() anchor, cyclical otherwise.
See Also
time_components() for the inverse operation, lin()/cyc() for
the component vocabulary shared with time_components() and format().
Examples
# cyc() values are 1-indexed positions: month 3 is March, day 15 is the 15th
time_compose(lin(year) ~ 1980, cyc(month, year) ~ 3, cyc(day, month) ~ 15)
# A lin() anchor alone is a valid (coarser) time point
time_compose(lin(year) ~ 1980)
# No lin() anchor: composes cyclical time
time_compose(cyc(month, year) ~ 3)
# Chaining collapses to one (chronon, cycle) pair: day 15 of month 3
# becomes day-of-year 74
time_compose(cyc(day, month) ~ 15, cyc(month, year) ~ 3)
# Round-tripping through time_components()
parts <- time_components(as.Date("2024-03-15"), yr = lin(year), mth = cyc(month, year))
with(parts, time_compose(yr, mth))
# Multi-unit (self-referencing) cycles: the 3rd month (1-indexed) of the
# 4th 3-month block since epoch (block 3 = months 9-11 -> December 1970)
time_compose(lin(month(3L)) ~ 3, cyc(month(1L), month(3L)) ~ 3)
Obtain the cycle of a time object
Description
This S7 generic function extracts the cycle (the cyclical time granule) from a time object, such as cyclical time representations.
Usage
time_cycle(x, ...)
Arguments
x |
A time object (e.g., base::Date, base::POSIXct, |
... |
Additional arguments for methods. |
Value
A time duration() object representing the cycle of each value
(e.g. weeks(1L)), or NA if the object has no cyclical component.
Examples
# Non-cyclical objects return NA
time_cycle(Sys.Date())
# The cycle of a cyclical time object
time_cycle(month_of_year(Sys.Date()))
Test whether a granule is completed at a time point
Description
time_is_complete_at() tests, for each element of a mixtime vector, whether
the coarser granule that element falls into is fully observed by the vector
as a whole – that is, whether every finer chronon making up that granule is
present somewhere in x.
Usage
time_is_complete_at(x, granule, ...)
Arguments
x |
A time object (typically a |
granule |
The time granule whose precision to test, given as a granule
generator (e.g. |
... |
Additional arguments for methods. |
Details
Unlike time_is_determinate_at(), completeness is a collective property: an
element is TRUE only when the other elements needed to fill its granule are
also present. For example, in year(1L) the months of 2020 Jan : 2020 Oct
are all FALSE (November and December are missing, so 2020 is incomplete),
whereas in 2020 Jan : 2021 Mar the twelve months of 2020 are TRUE (they
complete 2020) while the three months of 2021 remain FALSE.
A granule equal to x's own chronon is completed by each point on its own
(TRUE). A granule finer than x cannot be completed by coarser points
(FALSE). Missing (NA) and infinite times give NA.
Completeness is only defined within a single time granularity. Mixed-type
mixtime vectors (e.g. months alongside days) are not yet supported and
raise an error.
Value
A logical vector the same length as x.
See Also
Examples
# 2020 Jan : 2020 Oct does not complete the year -> all FALSE
time_is_complete_at(yearmonth(as.Date("2020-01-01")) + 0:9, cal_gregorian$year(1L))
# 2020 Jan : 2021 Mar completes 2020 (TRUE) but not 2021 (FALSE)
time_is_complete_at(yearmonth(as.Date("2020-01-01")) + 0:14, cal_gregorian$year(1L))
Test whether time is determinate at a granule's precision
Description
time_is_determinate_at() tests, for each element of a mixtime vector, whether
the time point is well-defined at the precision of granule.
Usage
time_is_determinate_at(x, granule, ...)
Arguments
x |
A time object (typically a |
granule |
The time granule whose precision to test, given as a granule
generator (e.g. |
... |
Additional arguments for methods. |
Details
Discrete (integer) time cannot resolve a granule finer than its own chronon (a
year() has no determinate month), so those elements are FALSE. Continuous
(fractional) time tracks progress within its chronon and so resolves finer
granules exactly (0% through 2020 is 0% through January), giving TRUE.
Coarser-or-equal granules are always determinate. Missing (NA) and infinite
times give NA.
Value
A logical vector the same length as x.
Examples
# Discrete: a year has no determinate month
time_is_determinate_at(year(2020L), cal_gregorian$month(1L))
# Continuous: 0% through 2020 is 0% through January
time_is_determinate_at(year(2020), cal_gregorian$month(1L))
# A coarser granule is always determinate
time_is_determinate_at(yearmonth(as.Date("2020-02-01")), cal_gregorian$year(1L))
Parse text into a time point
Description
time_parse() is the inverse of format(): given text and the same
{lin(...)}/{cyc(...)} template format uses, it reconstructs the time
points that would have produced that text, via time_compose().
Usage
time_parse(
x,
chronon = NULL,
cycle = NULL,
format = NULL,
regex = FALSE,
na = c("", "NA"),
calendar = NULL,
locale = NULL,
discrete = TRUE
)
Arguments
x |
A character vector to parse. |
chronon |
Target time granule for the result, and (with |
cycle |
Target cycle granule, pairing with |
format |
A glue-style format string of |
regex |
If |
na |
Strings to treat as missing ( |
calendar |
Calendar used to resolve granule names in |
locale |
Default locale for named ( |
discrete |
Whether the result is discrete (integer chronon counts)
or continuous (fractional). See |
Details
A format with a {lin(...)} token parses to linear time; one of only
{cyc(...)} tokens parses to cyclical time, e.g. time_parse("Feb", format = "{cyc(month, year, label = TRUE)}") recovers the same kind of
value as month_of_year().
Granule-specific extraction and decoding labels for each token is done by
linear_labels_parse()/cyclical_labels_parse().
Value
A mixtime time vector, the same length as x. Linear if
format includes a {lin(...)} token (or cycle is NULL),
cyclical otherwise.
See Also
format() for the inverse direction, time_compose() for
composing a time point from already-decoded components,
label_scheme() for declaring how a granule's labels parse,
chronon_parse_linear()/chronon_parse_cyclical() for the candidate
formats derived from chronon/cycle, and vignette("time-format-strings")
for the format string syntax.
Examples
time_parse("2024-02-15", format = "{lin(year)}-{cyc(month, year)}-{cyc(day, month)}")
time_parse(
"15 Feb 2024",
format = "{cyc(day, month)} {cyc(month, year, label = TRUE)} {lin(year)}"
)
# One bad value becomes NA (with a warning) instead of aborting the batch
time_parse(
c("2024-02-15", "not a date"),
format = "{lin(year)}-{cyc(month, year)}-{cyc(day, month)}"
)
# No {lin(...)} token: parses to cyclical time
time_parse("Feb", format = "{cyc(month, year, label = TRUE)}")
# Several formats: whichever parses the most values is used for the whole
# vector; here none of the "Y-M-D" format's values match, so the "D/M/Y"
# format (which matches both) is used instead
time_parse(
c("15/02/2024", "20/03/2024"),
format = c(
"{lin(year)}-{cyc(month, year)}-{cyc(day, month)}",
"{cyc(day, month)}/{cyc(month, year)}/{lin(year)}"
)
)
# regex = TRUE: match "/" or "-" as the separator,
# and tolerate a trailing comment after the date.
time_parse(
c("2024-02-15", "2024/02/15 (approx)"),
format = "{lin(year)}[/-]{cyc(month, year)}[/-]{cyc(day, month)}( .*)?",
regex = TRUE
)
# Default format strings from the target chronon, and results with `tz`.
time_parse("2024-02-15 09:00:00", chronon = cal_gregorian$second(1L, tz = "America/Los_Angeles"))
Round, floor and ceiling transformations for time objects
Description
A family of helpers to round date/time objects to a specified time granule
such as second, minute, hour, or day. These functions preserve the input
time class, as rounded by the attributes of the granule.
Usage
time_round(x, granule, ...)
time_ceiling(x, granule, ...)
time_floor(x, granule, ...)
Arguments
x |
A date/time object to be rounded. Accepted types include Date, POSIXct, POSIXlt and other objects that inherit from POSIXt. The returned object will be of the same class as the input. |
granule |
A time granule (or object coercible to a time granule, e.g. "day"). |
... |
Additional arguments passed to specific implementations. |
Value
An object of the same class as x with its time components adjusted to the requested granule.
See Also
base::round, lubridate::round_date
Examples
# Round POSIXct to the nearest minute (preserving tz)
t <- as.POSIXct("2020-01-01 12:34:56", tz = "UTC")
time_round(t, granule = cal_gregorian$minute(1L))
# Floor to the nearest hour
time_floor(t, granule = cal_gregorian$hour(1L))
# Ceiling a Date (treated as midnight-of-day rounding)
d <- as.Date("2020-01-01")
time_ceiling(d, granule = cal_gregorian$month(1L))
Time units as a string
Description
These S7 generic functions provide the full and abbreviated names for time
units. time_unit_full() is used in messages and durations (e.g., "2 months").
time_unit_abbr() is used for tsibble index interval displays (e.g., "1M").
time_unit_plural() pluralises the full unit name for a given quantity using
cli-style pluralisation (e.g., "year{?/s}" becomes "year" or "years").
Usage
time_unit_full(x, ...)
time_unit_plural(x, n = 2L)
time_unit_abbr(x, ...)
Arguments
x |
A time granule object (e.g., |
... |
Additional arguments for methods. |
n |
Numeric quantity used to select singular or plural form. |
Value
A string representing the time unit
Examples
time_unit_full(cal_gregorian$year(1L))
time_unit_plural(cal_gregorian$year(1L), 1L)
time_unit_plural(cal_gregorian$year(1L), 2L)
time_unit_abbr(cal_gregorian$year(1L))
Get timezone abbreviation
Description
Returns the timezone abbreviation (e.g., "EST", "PDT") for a given datetime in its specified timezone.
Usage
tz_abbreviation(x, tz = tz_name(x))
Arguments
x |
A POSIXct datetime object or something coercible to POSIXct. The timezone is extracted from this object. |
tz |
A character vector of timezones to abbreviate at time point |
Value
A character vector of timezone abbreviations.
Examples
tz_abbreviation(Sys.time())
tz_abbreviation(as.POSIXct("2024-01-15 12:00:00", tz = "America/New_York"))
Extract timezone from an object
Description
Generic function to extract the timezone from objects that have timezone information.
Usage
tz_name(x, ...)
Arguments
x |
An object with timezone information. |
... |
Additional arguments passed to methods. |
Value
A character vector representing the timezone of each time point (e.g., "America/New_York", "UTC").
Examples
tz_name(Sys.time())
tz_name(as.POSIXct("2024-06-15 12:00:00", tz = "America/New_York"))
Get timezone offset
Description
Returns the UTC offset for a given datetime in its specified timezone.
Usage
tz_offset(x, ...)
Arguments
x |
A time class coercible to POSIXt with an associated time zone. |
... |
Additional arguments passed to methods. |
Value
A mixtime duration vector of offsets from UTC in the same chronon
(e.g. seconds for POSIXt, days for dates, etc.)
Examples
tz_offset(as.POSIXct(Sys.time(), tz = Sys.timezone()))
tz_offset(as.POSIXct("2024-06-15 12:00:00", tz = "America/New_York"))
Get timezone transitions
Description
Returns all timezone transitions (e.g., daylight saving time changes) that occur between two datetimes. The timezone is taken from the start datetime.
Usage
tz_transitions(start, end)
Arguments
start |
A POSIXct datetime object or something coercible to POSIXct, representing the start of the time range. The timezone is extracted from this object. |
end |
A POSIXct datetime object or something coercible to POSIXct, representing the end of the time range. |
Value
A data frame with columns:
-
time: Amixtimelinear time point (continuous, UTC seconds) giving the instant of the transition. -
offset_before,offset_after:mixtimedurations (UTC seconds) giving the UTC offset immediately before and after the transition.
Examples
# Get all DST transitions in 2024 for New York
tz_transitions(
as.POSIXct("2024-01-01", tz = "America/New_York"),
as.POSIXct("2024-12-31", tz = "America/New_York")
)
Build a vocab function from a plain name table
Description
The common case for a label_scheme() vocab argument: a hand-listed
table of names, one entry per locale, each a named list of renderings. By
convention these follow CLDR's wide/abbreviated/narrow, but type can be
anything. vocab_table() wraps it in the function(type = NULL, locale = NULL) shape vocab requires.
Usage
vocab_table(..., default_locale = "en-GB")
Arguments
... |
Named entries, one per locale (e.g. |
default_locale |
The locale returned when |
Details
For vocab backed by an external i18n source instead of a hand-listed
table, write that function(type, locale) directly instead. Same shape,
no list needed.
Value
A function function(type = NULL, locale = NULL), suitable as
the vocab field of a label_scheme().
See Also
Examples
month_vocab <- vocab_table(`en-GB` = list(wide = month.name, abbreviated = month.abb))
month_vocab("abbreviated")
month_vocab(locale = "en-GB")