JalaliX (JalaliX v0.1.0)

Copy Markdown View Source

Jalali (Persian / Shamsi) calendar for Elixir.

Pure Elixir, no runtime timezone database dependency. Internally a JalaliX value is a UTC Unix millisecond instant (ms) plus an active IANA-style timezone id (timezone). Timezone support is intentionally simple: offsets for UTC and Asia/Tehran are hardcoded (Iran has not observed DST since 2022, so Asia/Tehran is a fixed +03:30 offset year-round). setTimezone/2 is instant-preserving: getTime/1 stays the same; only the wall-clock / Jalali display changes.

Elixir is immutable, so every "setter" returns a new %JalaliX{} struct rather than mutating in place.

Method names intentionally mirror the TypeScript/Python ports (@jalalix/typescript, jalalix on PyPI) using camelCase, so porting code between languages is mostly 1:1.

Month quirk

Just like the JS/Python ports:

  • getMonth/1 is 1-based (Farvardin = 1 .. Esfand = 12)
  • setMonth/2,3 and setFullYear/2,3,4 take a 0-based month (Farvardin = 0 .. Esfand = 11), matching JS Date.

Example

iex> d = JalaliX.create("2025-02-25")
iex> JalaliX.format(d, "YYYY/MM/DD")
"1403/12/07"
iex> JalaliX.parseJalali("1403/12/07") |> JalaliX.toISODate()
"2025-02-25"

Summary

Functions

Adds the given number of days (can be negative).

Adds the given number of Jalali months (can be negative).

Adds the given number of weeks (can be negative).

Adds the given number of Jalali years (can be negative).

Creates a copy of this JalaliX instance (same instant and timezone).

Returns true if a is before b.

Creates a JalaliX instance from a Gregorian date value.

Formats the date according to a format string.

Converts Persian numerals (۰-۹) to Western numerals (0-9) in a string.

Gets the day of the month in the Jalali calendar (1-31).

Gets the day of the week (1=Saturday .. 7=Friday in Jalali).

Gets the ISO day of the week (1=Monday .. 7=Sunday).

Gets the Jalali day of the year (1-366).

Returns a new instance set to the end of the current day (23:59:59.999).

Returns a new instance set to the end of the current Jalali month.

Returns a new instance set to the end of the current week (Friday).

Returns a new instance set to the end of the Jalali year (23:59:59.999).

Gets the Jalali year.

Gets the hour (0-23) using wall time in the active timezone.

Gets the hour in 12-hour format (1-12).

Gets the meridiem (AM/PM) in Persian.

Gets the milliseconds (0-999).

Gets the minutes (0-59) using wall time in the active timezone.

Gets the Jalali month (1-12, Farvardin = 1).

Gets the seconds (0-59) using wall time in the active timezone.

Returns a new instance set to the start of the current day (00:00:00.000).

Returns a new instance set to the start of the current Jalali month.

Returns a new instance set to the start of the current week (Saturday).

Returns a new instance set to the start of the Jalali year.

Gets the Unix millisecond timestamp.

Gets the active IANA timezone id of this instance.

Gets the Jalali week number of the year (1-53).

Returns true if value is a recognized date-like value.

Parses a Jalali date string into a JalaliX instance.

Sets the day of the month (Jalali) using wall time.

Sets the Jalali year (and optionally month/day) using wall time.

Sets the hour (and optionally minutes/seconds/milliseconds) using wall time.

Sets the milliseconds using wall time in the active timezone.

Sets the minutes (and optionally seconds/milliseconds) using wall time.

Sets the Jalali month using wall time.

Sets the seconds (and optionally milliseconds) using wall time.

Sets the Unix millisecond timestamp.

Creates a new JalaliX with the same UTC instant in a different timezone.

Date string with weekday, day, month, and year (no time).

Returns a calendar date string using wall getters in the active timezone (no UTC shift).

Locale-formatted date string: YYYY/MM/DD.

Time string with meridiem, e.g. 10:30:45 ق.ظ..

Converts Western numerals (0-9) to Persian numerals (۰-۹) in a string.

Full date string with weekday, day, month, year, and time.

Types

t()

@type t() :: %JalaliX{ms: integer(), timezone: String.t()}

Functions

addDays(j, days)

@spec addDays(t(), integer()) :: t()

Adds the given number of days (can be negative).

addMonths(j, months)

@spec addMonths(t(), integer()) :: t()

Adds the given number of Jalali months (can be negative).

addWeeks(j, weeks)

@spec addWeeks(t(), integer()) :: t()

Adds the given number of weeks (can be negative).

addYears(j, years)

@spec addYears(t(), integer()) :: t()

Adds the given number of Jalali years (can be negative).

clone(jalali_x)

@spec clone(t()) :: t()

Creates a copy of this JalaliX instance (same instant and timezone).

compare(a, b)

@spec compare(t(), t()) :: boolean()

Returns true if a is before b.

create(date, opts \\ %{})

@spec create(
  integer()
  | float()
  | String.t()
  | Date.t()
  | DateTime.t()
  | NaiveDateTime.t()
  | t(),
  map() | keyword()
) :: t()

Creates a JalaliX instance from a Gregorian date value.

Accepts a Unix millisecond timestamp (integer/float), an ISO8601 string, a Date/DateTime/NaiveDateTime, or another JalaliX.

opts may contain timezone: to set the active zone (map or keyword list).

format(j, pattern, persian_or_options \\ false, gregorian \\ false)

@spec format(t(), String.t(), boolean() | map() | keyword(), boolean()) :: String.t()

Formats the date according to a format string.

Prefer format(j, str, %{calendar: ..., persianDigits: ...}). Positional booleans remain supported: format(j, str, persianDigits?, gregorian?).

Tokens

YYYY YYY YY Y       year
MMM MM M            month name / number
W w                 week of year (padded / not)
DW dw WN wn WL wl    day-of-week (iso number / number / name / letter)
DDDD DDD             day of year (padded / not)
DD D                 day of month (padded / not)
HH H                 hour, 24h (padded / not)
hh h                 hour, 12h (padded / not)
mm m                 minutes (padded / not)
ss s                 seconds (padded / not)
SSS sss              milliseconds
A a                  meridiem
X x                  unix seconds / milliseconds

fromPersian(s)

@spec fromPersian(String.t()) :: String.t()

Converts Persian numerals (۰-۹) to Western numerals (0-9) in a string.

getDate(j)

@spec getDate(t()) :: integer()

Gets the day of the month in the Jalali calendar (1-31).

getDay(j)

@spec getDay(t()) :: integer()

Gets the day of the week (1=Saturday .. 7=Friday in Jalali).

getDayISO(j)

@spec getDayISO(t()) :: integer()

Gets the ISO day of the week (1=Monday .. 7=Sunday).

getDayOfYear(j)

@spec getDayOfYear(t()) :: integer()

Gets the Jalali day of the year (1-366).

getEndOfDay(j)

@spec getEndOfDay(t()) :: t()

Returns a new instance set to the end of the current day (23:59:59.999).

getEndOfMonth(j)

@spec getEndOfMonth(t()) :: t()

Returns a new instance set to the end of the current Jalali month.

getEndOfWeek(j)

@spec getEndOfWeek(t()) :: t()

Returns a new instance set to the end of the current week (Friday).

getEndOfYear(j)

@spec getEndOfYear(t()) :: t()

Returns a new instance set to the end of the Jalali year (23:59:59.999).

getFullYear(j)

@spec getFullYear(t()) :: integer()

Gets the Jalali year.

getHours(j)

@spec getHours(t()) :: integer()

Gets the hour (0-23) using wall time in the active timezone.

getHoursISO(j)

@spec getHoursISO(t()) :: integer()

Gets the hour in 12-hour format (1-12).

getMeridiem(j)

@spec getMeridiem(t()) :: String.t()

Gets the meridiem (AM/PM) in Persian.

getMilliseconds(j)

@spec getMilliseconds(t()) :: integer()

Gets the milliseconds (0-999).

getMinutes(j)

@spec getMinutes(t()) :: integer()

Gets the minutes (0-59) using wall time in the active timezone.

getMonth(j)

@spec getMonth(t()) :: integer()

Gets the Jalali month (1-12, Farvardin = 1).

getSeconds(j)

@spec getSeconds(t()) :: integer()

Gets the seconds (0-59) using wall time in the active timezone.

getStartOfDay(j)

@spec getStartOfDay(t()) :: t()

Returns a new instance set to the start of the current day (00:00:00.000).

getStartOfMonth(j)

@spec getStartOfMonth(t()) :: t()

Returns a new instance set to the start of the current Jalali month.

getStartOfWeek(j)

@spec getStartOfWeek(t()) :: t()

Returns a new instance set to the start of the current week (Saturday).

getStartOfYear(j)

@spec getStartOfYear(t()) :: t()

Returns a new instance set to the start of the Jalali year.

getTime(jalali_x)

@spec getTime(t()) :: integer()

Gets the Unix millisecond timestamp.

getTimezone(jalali_x)

@spec getTimezone(t()) :: String.t()

Gets the active IANA timezone id of this instance.

getWeekOfYear(j)

@spec getWeekOfYear(t()) :: integer()

Gets the Jalali week number of the year (1-53).

isValidDate(arg1)

@spec isValidDate(any()) :: boolean()

Returns true if value is a recognized date-like value.

parseJalali(value, opts \\ %{})

@spec parseJalali(String.t(), map() | keyword()) :: t()

Parses a Jalali date string into a JalaliX instance.

Accepts YYYY/MM/DD or YYYY-MM-DD, optional time (HH:mm / HH:mm:ss), and Persian digits.

setDate(j, date)

@spec setDate(t(), integer()) :: t()

Sets the day of the month (Jalali) using wall time.

setFullYear(j, year, month \\ nil, date \\ nil)

@spec setFullYear(t(), integer(), integer() | nil, integer() | nil) :: t()

Sets the Jalali year (and optionally month/day) using wall time.

month is 0-based (Farvardin = 0 .. Esfand = 11), matching JS Date.

setHours(j, hours, min \\ nil, sec \\ nil, ms \\ nil)

@spec setHours(t(), number(), number() | nil, number() | nil, number() | nil) :: t()

Sets the hour (and optionally minutes/seconds/milliseconds) using wall time.

setMilliseconds(j, ms)

@spec setMilliseconds(t(), number()) :: t()

Sets the milliseconds using wall time in the active timezone.

setMinutes(j, min, sec \\ nil, ms \\ nil)

@spec setMinutes(t(), number(), number() | nil, number() | nil) :: t()

Sets the minutes (and optionally seconds/milliseconds) using wall time.

setMonth(j, month, date \\ nil)

@spec setMonth(t(), integer(), integer() | nil) :: t()

Sets the Jalali month using wall time.

month is 0-based (Farvardin = 0 .. Esfand = 11), matching JS Date.

setSeconds(j, sec, ms \\ nil)

@spec setSeconds(t(), number(), number() | nil) :: t()

Sets the seconds (and optionally milliseconds) using wall time.

setTime(j, time)

@spec setTime(t(), number()) :: t()

Sets the Unix millisecond timestamp.

setTimezone(j, tz \\ nil)

@spec setTimezone(t(), String.t() | nil) :: t()

Creates a new JalaliX with the same UTC instant in a different timezone.

Instant-preserving: getTime/1 is unchanged; wall clock / Jalali day may change. Aliases: local/system/default -> host zone (or UTC), utc/gmt -> UTC. Raises ArgumentError for an unrecognized zone.

toDateString(j)

@spec toDateString(t()) :: String.t()

Date string with weekday, day, month, and year (no time).

toISODate(j, calendar \\ "gregorian")

@spec toISODate(t(), String.t()) :: String.t()

Returns a calendar date string using wall getters in the active timezone (no UTC shift).

calendar is "gregorian" (default, YYYY-MM-DD Gregorian) or "jalali" (Jalali YYYY-MM-DD).

toLocaleDateString(j)

@spec toLocaleDateString(t()) :: String.t()

Locale-formatted date string: YYYY/MM/DD.

toLocaleTimeString(j)

@spec toLocaleTimeString(t()) :: String.t()

Time string with meridiem, e.g. 10:30:45 ق.ظ..

toPersian(s)

@spec toPersian(String.t()) :: String.t()

Converts Western numerals (0-9) to Persian numerals (۰-۹) in a string.

toString(j)

@spec toString(t()) :: String.t()

Full date string with weekday, day, month, year, and time.