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(Weeks, -2, from_calendar_date(2018, Sep, 26))
== from_calendar_date(2018, Sep, 12)
When adding Years
or Months
, day values are clamped to the end of the
month if necessary.
add(Months, 1, from_calendar_date(2000, Jan, 31))
== 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(Tuesday, from_calendar_date(2018, May, 11))
== 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(Tuesday, from_calendar_date(2018, May, 11))
== 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(minimum, maximum, from_ordinal_date(1969, 201))
== 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 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"