rada/date
This module provides a simple Date type for working with dates without times or zones.
The module uses the Rata Die system to represent dates in the standard Gregorian Calendar. The number 1 represents the date 1 January 0001 and all other dates are represented as positive or negative numbers relative to that date.
Types
Represents a date.
The internal storage is a single Int using the Rata Die system. The
number 1 represents the date 1 January 0001 and all other dates are represented
as positive or negative numbers relative to that date.
pub opaque type Date
Interval indicator used in floor, ceiling and range functions. Allowing you to, for example, round a date
down to the nearest quarter, or week, or Tuesday, or whatever is required.
pub type Interval {
Year
Quarter
Month
Week
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Day
}
Constructors
-
Year -
Quarter -
Month -
Week -
Monday -
Tuesday -
Wednesday -
Thursday -
Friday -
Saturday -
Sunday -
Day
Functions to convert date information to strings in a custom language.
pub type Language {
Language(
month_name: fn(Month) -> String,
month_name_short: fn(Month) -> String,
weekday_name: fn(Weekday) -> String,
weekday_name_short: fn(Weekday) -> String,
day_with_suffix: fn(Int) -> String,
)
}
Constructors
-
Language( month_name: fn(Month) -> String, month_name_short: fn(Month) -> String, weekday_name: fn(Weekday) -> String, weekday_name_short: fn(Weekday) -> String, day_with_suffix: fn(Int) -> String, )
Represents the 12 months of the year.
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
Used in add and diff operations to specify natural increments as needed.
pub type Unit {
Years
Months
Weeks
Days
}
Constructors
-
Years -
Months -
Weeks -
Days
Functions
pub fn add(date: Date, count: Int, unit: Unit) -> Date
Get a past or future date by adding a number of units to a date.
add(from_calendar_date(2018, Sep, 26), -2, Weeks)
== from_calendar_date(2018, Sep, 12)
When adding Years or Months, day values are clamped to the end of the
month if necessary.
add(from_calendar_date(2000, Jan, 31), 1, Months)
== from_calendar_date(2000, Feb, 29)
pub fn ceiling(date: Date, interval: Interval) -> Date
Round up a date to the beginning of the closest interval. The resulting date will be greater than or equal to the one provided.
ceiling(from_calendar_date(2018, May, 11), Tuesday)
== from_calendar_date(2018, May, 15)
pub fn clamp(value: Date, lower: Date, upper: Date) -> Date
Clamp a date within a range.
let minimum = from_ordinal_date(1970, 1)
let maximum = from_ordinal_date(2038, 1)
clamp(from_ordinal_date(1969, 201), minimum, maximum)
== from_ordinal_date(1970, 1)
pub fn compare(date1: Date, date2: Date) -> Order
Compare two dates. This can be used as the compare function for
list.sort.
import gleam/ordering
compare(from_ordinal_date(1970, 1), from_ordinal_date(2038, 1))
== ordering.Lt
pub fn diff(unit: Unit, date1: Date, date2: Date) -> Int
Get the difference, as a number of whole units, between two dates.
diff(Months, from_calendar_date(2020, Jan, 2), from_calendar_date(2020, Apr, 1))
// -> 2
pub fn floor(date: Date, interval: Interval) -> Date
Round down a date to the beginning of the closest interval. The resulting date will be less than or equal to the one provided.
floor(from_calendar_date(2018, May, 11), Tuesday)
== from_calendar_date(2018, May, 8)
pub fn format(date: Date, pattern: String) -> String
Format a date using a string as a template.
from_ordinal_date(1970, 1)
|> format("EEEE, d MMMM y")
// -> "Thursday, 1 January 1970"
Alphabetic characters in the template represent date information; the number of
times a character is repeated specifies the form of a name (e.g. "Tue",
"Tuesday") or the padding of a number (e.g. "1", "01").
Alphabetic characters can be escaped within single-quotes; a single-quote can be escaped as a sequence of two single-quotes, whether appearing inside or outside an escaped sequence.
Templates are based on Date Format Patterns in Unicode Technical Standard #35. Only the following subset of formatting characters are available:
"y" -- year
"Y" -- week-numbering year
"Q" -- quarter
"M" -- month (number or name)
"w" -- week number
"d" -- day
"D" -- ordinal day
"E" -- weekday name
"e" -- weekday number
The non-standard pattern field “ddd” is available to indicate the day of the
month with an ordinal suffix (e.g. "1st", "15th"), as the current standard
does not include such a field.
pub fn format_with_language(
date: Date,
language: Language,
pattern_text: String,
) -> String
Format a date in a custom language using a string as a template.
// Assuming that `french_lang` is a custom `Language` value
from_ordinate_date(1970, 1)
|> format_with_language(french_lang, "EEEE, ddd MMMM y")
// -> "jeudi, 1er janvier 1970"
pub fn from_calendar_date(
year: Int,
month: Month,
day: Int,
) -> Date
Create a date from a calendar date: a year, month, and day of the month. Out-of-range day values will be clamped.
from_calendar_date(2018, Sep, 26)
pub fn from_iso_string(str: String) -> Result(Date, String)
Attempt to create a date from a string in ISO 8601 format. Calendar dates, week dates, and ordinal dates are all supported in extended and basic format.
// calendar date
from_iso_string("2018-09-26") == Ok(from_calendar_date(2018, Sep, 26))
// week date
from_iso_string("2018-W39-3") == Ok(from_week_date(2018, 39, Wed))
// ordinal date
from_iso_string("2018-269") == Ok(from_ordinal_date(2018, 269))
The string must represent a valid date; unlike from_calendar_date and
friends, any out-of-range values will fail to produce a date.
from_iso_string("2018-02-29") == Error("Invalid calendar date (2018, 2, 29)")
pub fn from_ordinal_date(year: Int, ordinal: Int) -> Date
Create a date from an ordinal date: a year and day of the year. Out-of-range day values will be clamped.
from_ordinal_date(2018, 269)
pub fn from_rata_die(rd: Int) -> Date
Rata Die where the number 1 represents the date 1 January 0001. Rata Die is a system for assigning numbers to calendar days,
You can losslessly convert a Date to and from an Int representing the date
in Rata Die. This makes it a convenient representation for transporting dates
or using them as comparables. For all date values:
{ date |> to_rata_die |> from_rata_die } == date
pub fn from_week_date(
week_year: Int,
week_number: Int,
weekday: Weekday,
) -> Date
Create a date from an ISO week date: a week-numbering year, week number, and weekday. Out-of-range week number values will be clamped.
from_week_date(2018, 39, Wed)
pub fn is_between(value: Date, lower: Date, upper: Date) -> Bool
Test if a date is within a range, inclusive of the range values.
let minimum = from_ordinal_date(1970, 1)
let maximum = from_ordinal_date(2038, 1)
is_between(from_ordinal_date(1969, 201), minimum, maximum)
== False
pub fn max(date1: Date, date2: Date) -> Date
Find the greater of two dates.
max(from_ordinal_date(1970, 1), from_ordinal_date(2038, 1))
== from_ordinal_date(2038, 1)
pub fn min(date1: Date, date2: Date) -> Date
Find the lesser of two dates.
min(from_ordinal_date(1970, 1), from_ordinal_date(2038, 1))
== from_ordinal_date(1970, 1)
pub fn month_to_number(month: Month) -> Int
Converts the month values Jan–Dec to 1–12.
pub fn number_to_month(month_number: Int) -> Month
Converts the numbers 1–12 to Jan–Dec. The input is clamped to the range 1-12 before conversion.
pub fn number_to_weekday(weekday_number: Int) -> Weekday
Converts the numbers 1–7 to Mon–Sun. The input is clamped to the range 1-7 before conversion.
pub fn range(
interval: Interval,
step: Int,
start_date: Date,
until_date: Date,
) -> List(Date)
Create a list of dates, at rounded intervals, increasing by a step value, between two dates. The list will start on or after the first date, and end before the second date.
let start = from_calendar_date(2018, May, 8)
let until = from_calendar_date(2018, May, 14)
range(Day, 2, start, until)
== [ from_calendar_date(2018, May, 8)
, from_calendar_date(2018, May, 10)
, from_calendar_date(2018, May, 12)
]
pub fn to_iso_string(date: Date) -> String
Convert a date to a string in ISO 8601 extended format.
from_calendar_date(2001, Jan, 1)
|> to_iso_string
// -> "2001-01-01"
pub fn to_rata_die(date: Date) -> Int
Convert a date to its number representation in Rata Die (see
from_rata_die). For all date values:
{ date |> to_rata_die |> from_rata_die } == date
pub fn week_year(date: Date) -> Int
The ISO week-numbering year. This is not always the same as the calendar year.
pub fn weekday_number(date: Date) -> Int
The weekday number (1–7), beginning with Monday.
from_calendar_date(2020, 03, 04) |> weekday_number
// -> 3
pub fn weekday_to_number(weekday: Weekday) -> Int
Converts the weekday values Mon–Sun to 1–7.
pub fn with_ordinal_suffix(value: Int) -> String
Convert an integer into an English ordinal number string (like "4th").
with_ordinal_suffix(21) == "21st"
with_ordinal_suffix(42) == "42nd"
with_ordinal_suffix(0) == "0th"
with_ordinal_suffix(23) == "23rd"
with_ordinal_suffix(-1) == "-1st"