mixtime mixtime website

R-CMD-check Lifecycle: experimental

mixtime provides flexible time classes for time series analysis and forecasting with mixed temporal granularities. It is designed for handling temporal data at different frequencies, making it ideal for:

Key Features

📈 Linear Time - Create linear time vectors with linear_time() or with helpers:

🔄 Cyclical Time - Create cyclical time vectors with cyclical_time() or with helpers:

⏳ Time durations - Create time duration vectors with duration() or with helpers:

🕰️ Time types

📅 Calendar Systems - Support for several calendars:

🧮 Temporal Operations

Installation

The mixtime package can be installed from CRAN with:

install.packages("mixtime")

The development version can be installed from GitHub with:

# install.packages("remotes")
remotes::install_github("mitchelloharawild/mixtime")

Usage

library(mixtime)
#> 
#> Attaching package: 'mixtime'
#> The following objects are masked from 'package:base':
#> 
#>     date, months, quarters
demo_time <- as.POSIXct("2026-02-22 18:30:42", tz = "UTC")
demo_date <- as.Date("2026-02-22")

The mixtime package is designed around the time units of calendars. These time units are used to create and manipulate time vectors.

Calendars and time units

Calendars have a cal_* prefix, which contain a set of time units that can be accessed with <cal>$<unit>. Using time units as functions produces time granules.

# The Gregorian calendar
cal_gregorian
#> <cal_gregorian>
#> Time units:
#>   - year
#>   - quarter
#>   - month
#>   - day
#>   - ampm
#>   - hour
#>   - minute
#>   - second
#>   - millisecond

# A 1-month time granule
cal_gregorian$month(1L) # (1L is integer 1)
#> <mixtime::tu_month>
#>  @ n : int 1
#>  @ tz: chr ""

# A 2-week time granule (fortnights)
cal_isoweek$week(2L)
#> <mixtime::tu_week>
#>  @ n : int 2
#>  @ tz: chr ""

Linear Time

A linear time vector uses time granules to define the resolution of time points, known as a chronon (the smallest granules of time). When the input time has a different resolution than the chronon, it will be automatically converted.

linear_time(demo_date, chronon = cal_gregorian$month(1L))
#> <mixtime[1]>
#> [1] 2026 Feb

Discrete time models (integer-based values) are used by default, however continuous time models (double-based values) can be used with discrete = FALSE to allow fractional chronons.

# February 22nd is 75% through the month (in non-leap years)
linear_time(demo_date, chronon = cal_gregorian$month(1L), discrete = FALSE)
#> <mixtime[1]>
#> [1] 2026 Feb 75.0%

Linear time helper functions are available to quickly create common time points.

# Create time vectors at different granularities
yearquarter(demo_date) + 0:7
#> <mixtime[8]>
#> [1] 2026 Q1 2026 Q2 2026 Q3 2026 Q4 2027 Q1 2027 Q2 2027 Q3 2027 Q4
yearmonth(demo_date) + 0:11
#> <mixtime[12]>
#>  [1] 2026 Feb 2026 Mar 2026 Apr 2026 May 2026 Jun 2026 Jul 2026 Aug 2026 Sep
#>  [9] 2026 Oct 2026 Nov 2026 Dec 2027 Jan
yearweek(demo_date) + 0:10
#> <mixtime[11]>
#>  [1] 2026 W08 2026 W09 2026 W10 2026 W11 2026 W12 2026 W13 2026 W14 2026 W15
#>  [9] 2026 W16 2026 W17 2026 W18
date(demo_date) + 0:6
#> <mixtime[7]>
#> [1] 2026-02-22 2026-02-23 2026-02-24 2026-02-25 2026-02-26 2026-02-27 2026-02-28

The mixtime package allows time of different granulities to be combined in a single vector.

c(
  year(demo_date), yearquarter(demo_date), 
  yearmonth(demo_date), yearweek(demo_date)
)
#> <mixtime[4]>
#> [1] 2026     2026 Q1  2026 Feb 2026 W08

Cyclical Time

A cyclical time vector is defined by two time granules: a chronon (the smaller granule of time) and a cycle (the larger granule that the chronon loops over).

# The `calendar` argument provides a masking scope to `chronon` and `cycle`
cyclical_time(demo_date, chronon = day(1L), cycle = week(1L), calendar = cal_isoweek)
#> <mixtime[1]>
#> [1] Sun

There are several cyclical time helper functions for convenience.

# Extract cyclical components
month_of_year(demo_date)
#> <mixtime[1]>
#> [1] Feb
week_of_year(demo_date)
#> <mixtime[1]>
#> [1] W08
day_of_week(demo_date)
#> <mixtime[1]>
#> [1] Sun

# Continuous cyclical time shows progress through chronons
day_of_week(demo_time, discrete = FALSE)
#> <mixtime[1]>
#> [1] Sun 77.1%

Timezones

All linear and cyclical time vectors support timezones via the tz argument.

demo_time
#> [1] "2026-02-22 18:30:42 UTC"
# Same day (Sunday) in LA
date(demo_time, tz = "America/Los_Angeles")
#> <mixtime[1]>
#> [1] 2026-02-22 PST
date(demo_time, tz = "America/Los_Angeles", discrete = FALSE)
#> <mixtime[1]>
#> [1] 2026-02-22 PST 43.8%
day_of_week(demo_time, tz = "America/Los_Angeles")
#> <mixtime[1]>
#> [1] Sun PST

# Next day (Monday) in Melbourne (23% through the 23rd)
date(demo_time, tz = "Australia/Melbourne")
#> <mixtime[1]>
#> [1] 2026-02-23 AEDT
date(demo_time, tz = "Australia/Melbourne", discrete = FALSE)
#> <mixtime[1]>
#> [1] 2026-02-23 AEDT 23.0%
day_of_week(demo_time, tz = "Australia/Melbourne")
#> <mixtime[1]>
#> [1] Mon AEDT

Temporal Manipulation

Linear time points can be adjusted to the floor, ceiling, or rounded to a specified time granule.

# Round dates to different granularities
time_floor(demo_date, cal_gregorian$month(1L))
#> [1] "2026-02-01"
time_round(demo_date, cal_isoweek$week(1L))
#> [1] "2026-02-23"
time_ceiling(demo_date, cal_gregorian$month(1L))
#> [1] "2026-03-01"

Time Sequences

The seq() function creates sequences of time points iterating by a given time granule.

# Integer increments (advances by chronon's natural granule)
seq(yearmonth(demo_date), by = 1L, length.out = 10)
#> <mixtime[10]>
#>  [1] 2026 Feb 2026 Mar 2026 Apr 2026 May 2026 Jun 2026 Jul 2026 Aug 2026 Sep
#>  [9] 2026 Oct 2026 Nov

# Time can be sequenced by different granules than the chronon
seq(date(demo_date), by = cal_gregorian$month(1L), length.out = 8)
#> <mixtime[8]>
#> [1] 2026-02-22 2026-03-22 2026-04-22 2026-05-22 2026-06-22 2026-07-22 2026-08-22
#> [8] 2026-09-22