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
-
-
LocalDateTime( date: Date, time: Time, offset: Offset, tz: TimeZoneProvider, )
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
-
MonthYear(month: calendar.Month, year: Int)
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
-
TimeZoneProvider( get_name: fn() -> String, calculate_offset: fn(NaiveDateTime) -> Offset, )
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"