Skip to contents

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:

  • Changing observation frequencies (e.g., historical quarterly records now reported monthly)
  • Analysis involving data at different temporal resolutions (e.g., quarterly tourism and monthly turnover)
  • Forecasting with temporal reconciliation across multiple time scales

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 types

  • Discrete and continuous time models
  • Timezone support for all chronons
  • Custom granule sizes (e.g. week(2L) for fortnights)
  • Mixed granularity vectors for different temporal resolution over time (or series)

📅 Calendar Systems - Support for several calendars:

  • cal_gregorian - Gregorian dates (e.g. 2026-02-17)
  • cal_isoweek - ISO week dates (e.g. 2026-W8-Tue)
  • More calendars coming, including custom censored 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 object is masked from 'package:base':
#> 
#>     date
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>.

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

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

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

Linear Time

A linear time vector uses time units to define the resolution of time points, known as a chronon (the smallest unit 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 calendar time units: a chronon (the smaller unit of time) and a cycle (the larger unit 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 unit.

# Round dates to different granularities
floor_time(demo_date, cal_gregorian$month(1L))
#> Date of length 0
round_time(demo_date, cal_isoweek$week(1L))
#> Date of length 0
ceiling_time(demo_date, cal_gregorian$month(1L))
#> Date of length 0

Time Sequences

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

# Integer increments (advances by chronon's natural unit)
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

# Calendar time units allow sequencing by other units
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