tempo

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

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

A datetime value with a timezone 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.

pub opaque type DateTime

A duration between two times. It represents a range of time values and can be span more than a day. It can be used to calculate the number of days, weeks, hours, minutes, or seconds between two times, but cannot accurately be used to calculate the number of years or months between.

It is also used as the basis for specifying how to increase or decrease a datetime or time value.

pub opaque type Duration
pub type Error {
  TimeInvalidFormat
  TimeOutOfBounds
  DateInvalidFormat
  DateOutOfBounds
  MonthInvalidFormat
  MonthOutOfBounds
  OffsetInvalidFormat
  OffsetOutOfBounds
  NaiveDateTimeInvalidFormat
  DateTimeInvalidFormat
  InvalidInputShape
  UnableToParseDirective(String)
  ParseMissingDate
  ParseMissingTime
  ParseMissingOffset
}

Constructors

  • TimeInvalidFormat
  • TimeOutOfBounds
  • DateInvalidFormat
  • DateOutOfBounds
  • MonthInvalidFormat
  • MonthOutOfBounds
  • OffsetInvalidFormat
  • OffsetOutOfBounds
  • NaiveDateTimeInvalidFormat
  • DateTimeInvalidFormat
  • InvalidInputShape
  • UnableToParseDirective(String)
  • ParseMissingDate
  • ParseMissingTime
  • ParseMissingOffset
pub type MonotonicTime {
  MonotonicTime(nanoseconds: Int, unique: Int)
}

Constructors

  • MonotonicTime(nanoseconds: Int, unique: Int)

A specific month on the civil calendar.

pub type Month {
  Jan
  Feb
  Mar
  Apr
  May
  Jun
  Jul
  Aug
  Sep
  Oct
  Nov
  Dec
}

Constructors

  • Jan
  • Feb
  • Mar
  • Apr
  • May
  • Jun
  • Jul
  • Aug
  • Sep
  • Oct
  • Nov
  • Dec

A month in a specific year.

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

Constructors

  • MonthYear(month: Month, year: Int)

A datetime value that does not have a timezone offset associated with it. It cannot be compared to datetimes with a timezone offset accurately, but can be compared to dates, times, and other naive datetimes.

pub opaque type NaiveDateTime

A timezone 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 type Period {
  NaivePeriod(start: NaiveDateTime, end: NaiveDateTime)
  Period(start: DateTime, end: DateTime)
}

Constructors

  • NaivePeriod(start: NaiveDateTime, end: NaiveDateTime)
  • Period(start: DateTime, end: DateTime)

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 can have different precisions between second and nanosecond, depending on what your application needs.

Do not use the == operator to check for time equality (it will not handle time precision correctly)! Use the compare functions instead.

pub opaque type Time

The result of an uncertain conversion. Since this package does not track timezone offsets, it uses the host system’s offset to convert to local time. If the datetime being converted to local time is of a different day than the current one, the offset value provided by the host may not be accurate (and could be accurate by up to the amount the offset changes throughout the year). To account for this, when converting to local time, a precise value is returned when the datetime being converted is in th current date, while an imprecise value is returned when it is on any other date. This allows the application logic to handle the two cases differently: some applications may only need to convert to local time on the current date or may only need generic time representations, while other applications may need precise conversions for arbitrary dates. More notes on how to plug time zones into this package to aviod uncertain conversions can be found in the README.

pub type UncertainConversion(a) {
  Precise(a)
  Imprecise(a)
}

Constructors

  • Precise(a)
  • Imprecise(a)

Constants

pub const months: List(Month)

An ordered list of all months in the year.

pub const utc: Offset

The Tempo representation of the UTC offset.

Functions

pub fn accept_imprecision(conv: UncertainConversion(a)) -> a

Accepts either a precise or imprecise value of an uncertain conversion. Useful for pipelines.

Examples

datetime.literal("2024-06-21T23:17:00Z")
|> datetime.to_local
|> tempo.accept_imprecision
|> datetime.to_string
// -> "2024-06-21T19:17:00-04:00"
pub fn error_on_imprecision(
  conv: UncertainConversion(a),
) -> Result(a, Nil)

Either returns a precise value or an error from an uncertain conversion. Useful for pipelines.

Examples

datetime.literal("2024-06-21T23:17:00Z")
|> datetime.to_local
|> tempo.error_on_imprecision
|> result.try(do_important_precise_task)
pub fn parse_any(
  str: String,
) -> Result(#(Option(Date), Option(Time), Option(Offset)), Error)

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.

Example

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

  Ok(#(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")
// -> Ok(#(
//  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")
// -> Ok(#(
//  Some(date.literal("2024-12-25")), 
//  Some(time.literal("06:00:00")),
//  None
// ))
Search Document