tempo

The main module of this package. Contains most package types and general purpose functions. Look in specific modules for more functionality!

Calendar

Every date this package accepts or produces is a proleptic Gregorian calendar date, with Gregorian month lengths and the Gregorian leap year rule (divisible by 4, except century years, which must be divisible by 400). “Proleptic” means those rules are applied to dates before the calendar’s 1582 adoption too, so early dates do not line up with what was recorded historically on the Julian calendar. No other calendar system is supported.

Month and day names, and the formatting and parsing directives that use them, are the English Gregorian ones. This package is not a localisation library; for a user-facing international audience use alternative packages like g18n or intldate.

Range of valid dates

Constructing a date from calendar parts is limited to years 1000 through 9999, so that a year is always four digits. Every constructor that takes a year, a tuple, or a string rejects years outside that range. Date arithmetic is not range checked and can carry a value outside it, where it still compares correctly but no longer formats as valid ISO 8601. See the tempo/date module docs for the details.

Times run from 00:00:00.000000 through 23:59:59.999999, with 24:00:00 and the leap second 23:59:60 additionally accepted; see the tempo/time module docs. Offsets run from -12:00 through +14:00; see tempo/offset. Durations carry no calendar context at all; see tempo/duration.

Types

A date value. It represents a specific day on the civil calendar with no time of day associated with it.

pub opaque type Date

Provides common date formatting templates.

The CustomDate format takes a format string that implements the same formatting directives as the nice Day.js library: https://day.js.org/docs/en/display/format.

Values can be escaped by putting brackets around them, like “[Hello!] YYYY”.

Available custom format directives: YY (two-digit year), YYYY (four-digit year), M (month), MM (two-digit month), MMM (short month name), MMMM (full month name), D (day of the month), DD (two-digit day of the month), d (day of the week), dd (min day of the week), ddd (short day of week), and dddd (full day of the week).

pub type DateFormat {
  ISO8601Date
  CustomDate(format: String)
  CustomDateLocalised(format: String, locale: Locale)
}

Constructors

  • ISO8601Date
  • CustomDate(format: String)
  • CustomDateLocalised(format: String, locale: Locale)

A datetime value with a time zone offset associated with it. It has the most amount of information about a point in time, and can be compared to all other types in this package by getting its lesser parts.

pub type DateTime {
  DateTime(date: Date, time: Time, offset: Offset)
  LocalDateTime(
    date: Date,
    time: Time,
    offset: Offset,
    tz: TimeZoneProvider,
  )
}

Constructors

Provides common datetime formatting templates.

The Custom format takes a format string that implements the same formatting directives as the nice Day.js library: https://day.js.org/docs/en/display/format, plus condensed offsets.

Values can be escaped by putting brackets around them, like “[Hello!] YYYY”.

Available custom format directives: YY (two-digit year), YYYY (four-digit year), M (month), MM (two-digit month), MMM (short month name), MMMM (full month name), D (day of the month), DD (two-digint day of the month), d (day of the week), dd (min day of the week), ddd (short day of week), dddd (full day of the week), H (hour), HH (two-digit hour), h (12-hour clock hour), hh (two-digit 12-hour clock hour), m (minute), mm (two-digit minute), s (second), ss (two-digit second), SSS (millisecond), SSSS (microsecond), Z (offset from UTC), ZZ (offset from UTC with no “:”), z (short offset from UTC “-04”, “Z”), A (AM/PM), a (am/pm).

pub type DateTimeFormat {
  ISO8601Seconds
  ISO8601Milli
  ISO8601Micro
  HTTP
  Custom(format: String)
  CustomLocalised(format: String, locale: Locale)
  DateFormat(DateFormat)
  TimeFormat(TimeFormat)
}

Constructors

  • ISO8601Seconds
  • ISO8601Milli
  • ISO8601Micro
  • HTTP
  • Custom(format: String)
  • CustomLocalised(format: String, locale: Locale)
  • DateFormat(DateFormat)
  • TimeFormat(TimeFormat)

A monotonic type that represents a unique point in time on the host system. It can be converted to all other date time types but cannot be serialized itself. An instant constructed on one host has no meaningful purpose on another host.

pub opaque type Instant

A type that provides information on how to format dates and times for a specific region or language.

pub type Locale

A month in a specific year.

pub type MonthYear {
  MonthYear(month: calendar.Month, year: Int)
}

Constructors

A datetime value with no time zone or offset associated with it. It cannot be compared to datetimes with a time zone offset accurately, but can be compared to dates, times, and other naive datetimes.

pub type NaiveDateTime {
  NaiveDateTime(date: Date, time: Time)
}

Constructors

Provides common naive datetime formatting templates.

The CustomNaive format takes a format string that implements the same formatting directives as the nice Day.js library: https://day.js.org/docs/en/display/format, plus condensed offsets.

Values can be escaped by putting brackets around them, like “[Hello!] YYYY”.

Available custom format directives: YY (two-digit year), YYYY (four-digit year), M (month), MM (two-digit month), MMM (short month name), MMMM (full month name), D (day of the month), DD (two-digint day of the month), d (day of the week), dd (min day of the week), ddd (short day of week), dddd (full day of the week), H (hour), HH (two-digit hour), h (12-hour clock hour), hh (two-digit 12-hour clock hour), m (minute), mm (two-digit minute), s (second), ss (two-digit second), SSS (millisecond), SSSS (microsecond), Z (full offset from UTC in the format “+-00:00”), ZZ (full offset from UTC with no “:”), z (short offset from UTC as “-04” or “Z” if UTC), zz (full offset from UTC as “-04:00” or “Z” if UTC), A (AM/PM), a (am/pm), or GMT (to parse “GMT” as a 0 offset from UTC).

pub type NaiveDateTimeFormat {
  NaiveISO8601Seconds
  NaiveISO8601Milli
  NaiveISO8601Micro
  CustomNaive(format: String)
  CustomNaiveLocalised(format: String, locale: Locale)
  NaiveDateFormat(DateFormat)
  NaiveTimeFormat(TimeFormat)
}

Constructors

  • NaiveISO8601Seconds
  • NaiveISO8601Milli
  • NaiveISO8601Micro
  • CustomNaive(format: String)
  • CustomNaiveLocalised(format: String, locale: Locale)
  • NaiveDateFormat(DateFormat)
  • NaiveTimeFormat(TimeFormat)

A datetime offset value. It represents the difference between UTC and the datetime value it is associated with.

pub opaque type Offset

A period between two calendar datetimes. It represents a range of datetimes and can be used to calculate the number of days, weeks, months, or years between two dates. It can also be interated over and datetime values can be checked for inclusion in the period.

pub opaque type Period

A time of day value. It represents a specific time on an unspecified date. It cannot be greater than 24 hours or less than 0 hours. It has microsecond precision.

pub opaque type Time

Provides common time formatting templates.

The CustomTime format takes a format string that implements the same formatting directives as the nice Day.js library: https://day.js.org/docs/en/display/format.

Values can be escaped by putting brackets around them, like “[Hello!] HH”.

Available custom format directives: H (hour), HH (two-digit hour), h (12-hour clock hour), hh (two-digit 12-hour clock hour), m (minute), mm (two-digit minute), s (second), ss (two-digit second), SSS (millisecond), SSSS (microsecond), A (AM/PM), or a (am/pm).

pub type TimeFormat {
  ISO8601TimeSeconds
  ISO8601TimeMilli
  ISO8601TimeMicro
  CustomTime(format: String)
  CustomTimeLocalised(format: String, locale: Locale)
}

Constructors

  • ISO8601TimeSeconds
  • ISO8601TimeMilli
  • ISO8601TimeMicro
  • CustomTime(format: String)
  • CustomTimeLocalised(format: String, locale: Locale)

A type that provides the information needed to convert datetimes between time zones. Use the tempo/time_zone module to construct one, or provide your own if you have another source of time zone data.

The tempo/time_zone module sources its data from the host: the operating system’s TZif database in /usr/share/zoneinfo on Erlang (macOS and other Unix systems), and the native Intl API on JavaScript.

pub type TimeZoneProvider {
  TimeZoneProvider(
    get_name: fn() -> String,
    calculate_offset: fn(NaiveDateTime) -> Offset,
  )
}

Constructors

Values

pub fn compare(to datetime: DateTime) -> order.Order

Compares the current system time to the provided datetime value.

Example

tempo.compare(datetime.literal("2024-12-26T00:00:00Z"))
// -> order.Lt
pub fn date_from_rata_die(rata_die: Int) -> Date

Creates a date from a Rata Die value, the number of days since the day before 0001-01-01 on the proleptic Gregorian calendar. So Rata Die 1 is 0001-01-01, and 719_163 is the Unix epoch 1970-01-01.

This is not range checked, so unlike the calendar-part constructors it will return dates outside the 1000 to 9999 year range, including year zero and negative years for values of 0 and below.

Prefer date.from_rata_die, which is the same function exposed on the date module.

pub fn date_to_rata_die(date: Date) -> Int

Returns the Rata Die value of a date, the number of days since the day before 0001-01-01 on the proleptic Gregorian calendar. So 0001-01-01 is 1, and the Unix epoch 1970-01-01 is 719_163.

Prefer date.to_rata_die, which is the same function exposed on the date module.

pub fn difference(from start: DateTime) -> duration.Duration

Gets the difference between the current system datetime and the provided datetime.

Example

tempo.difference(from: datetime.literal("2024-10-26T00:00:00Z"))
|> duration.format
// -> "54 days, 13 hours, and 46 minutes"
pub fn format_local(in format: DateTimeFormat) -> String

Formats the current local system time using the provided format, rendering proleptic Gregorian calendar values with English month and day names.

Example

tempo.format_local(tempo.ISO8601Seconds)
// -> "2024-12-26T12:32:34-04:00"
pub fn format_utc(in format: DateTimeFormat) -> String

Formats the current UTC system time using the provided format, rendering proleptic Gregorian calendar values with English month and day names.

Example

tempo.format_utc(tempo.ISO8601Seconds)
// -> "2024-12-26T16:32:34Z"
pub fn is_earlier(than datetime: DateTime) -> Bool

Checks if the current system time is earlier than the provided datetime.

Example

tempo.is_earlier(than: datetime.literal("2024-12-26T00:00:00Z"))
// -> False
pub fn is_earlier_or_equal(to datetime: DateTime) -> Bool

Checks if the current system time is earlier or equal to the provided datetime.

Example

tempo.is_earlier_or_equal(to: datetime.literal("2024-12-26T00:00:00Z"))
// -> True
pub fn is_equal(to datetime: DateTime) -> Bool

Checks if the current system time is equal to the provided datetime.

Example

tempo.is_equal(to: datetime.literal("2024-12-26T00:00:00Z"))
// -> False
pub fn is_later(than datetime: DateTime) -> Bool

Checks if the current system time is later than the provided datetime.

Example

tempo.is_later(than: datetime.literal("2024-12-26T00:00:00Z"))
// -> True
pub fn is_later_or_equal(to datetime: DateTime) -> Bool

Checks if the current system time is later or equal to the provided datetime.

Example

tempo.is_later_or_equal(to: datetime.literal("2024-12-26T00:00:00Z"))
// -> True
pub fn parse_any(
  str: String,
) -> #(
  option.Option(Date),
  option.Option(Time),
  option.Option(Offset),
)

Tries to parse a given date string without a known format. It will not parse two digit years and will assume the month always comes before the day in a date. Always prefer to use a module’s specific parse function when possible.

Using pattern matching, you can explicitly specify what to with the missing values from the input. Many libaries will assume a missing time value means 00:00:00 or a missing offset means UTC. This design lets the user decide how fallbacks are handled.

Any date found is read as a proleptic Gregorian calendar date and must have a four-digit year between 1000 and 9999, since two digit years are not parsed. Month names are matched against the English Gregorian ones.

Example

case tempo.parse_any("06/21/2024 at 01:42:11 PM") {
  #(Some(date), Some(time), Some(offset)) ->
    datetime.new(date, time, offset)

  #(Some(date), Some(time), None) ->
    datetime.new(date, time, offset.local())

  _ -> datetime.now_local()
}
// -> datetime.literal("2024-06-21T13:42:11-04:00")
tempo.parse_any("2024.06.21 11:32 AM -0400")
// -> #(
//  Some(date.literal("2024-06-21")),
//  Some(time.literal("11:32:00")),
//  Some(offset.literal("-04:00"))
// )
tempo.parse_any("Dec 25, 2024 at 6:00 AM")
// -> #(
//  Some(date.literal("2024-12-25")),
//  Some(time.literal("06:00:00")),
//  None
// )
pub fn since(start start: DateTime) -> duration.Duration

Gets the time since the provided datetime relative to the current system time. The same as tempo.difference, but a duration of 0 will be returned instead if the datetime is in the future.

Example

tempo.since(datetime.literal("2024-10-26T00:00:00Z"))
|> duration.format
// -> "54 days, 13 hours, and 46 minutes"
tempo.since(datetime.literal("9099-12-26T00:00:00Z"))
|> duration.format
// -> "none"
pub fn sleep(for duration: duration.Duration) -> Nil

Sleeps the current process for the provided duration. If the duration is less than a millisecond, the process will not sleep at all.

pub fn until(end end: DateTime) -> duration.Duration

Gets the time until the provided datetime relative to the current system time. A duration of 0 will be returned if the datetime is in the past.

Example

tempo.until(datetime.literal("2024-10-26T00:00:00Z"))
|> duration.format
// -> "none"
tempo.until(datetime.literal("2025-02-26T00:00:00Z"))
|> duration.format
// -> "54 days, 13 hours, and 46 minutes"
Search Document