Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

date

import date

This modules provides Zuri’s implementation of date and time manipulation methods. This module implements civil dates as well as julian dates.

Definitions

  • The calendar date (class Date) is a particular day of a calendar year, identified by its ordinal number within a calendar month within that year.

  • The Julian date number (jd) is in elapsed days and time since noon (Greenwich Mean Time) on January 1, 4713 BCE (in the Julian calendar).

Date instances support ordering (<, <=, >, >=) and equals() by comparing the underlying instant in time: see [[date.Date.equals]] for how that interacts with gmt_offset. Arithmetic is done through named methods rather than +/- (add_seconds, add_days, add_months, …; see [[date.Date.add_seconds]] and [[date.Date.add_months]]) since a plain number added to a date is otherwise ambiguous about its unit.

The module is callable. date(...) is the same call as date.date(...), documented below.

The date API

Every public name in date, wherever it is declared. Each links to the page that documents it.

NameKindSummary
date.DateclassDate and Time manipulation class
date.MAX_DAYconstantMaximum day supported.
date.MAX_HOURconstantMaximum hour supported.
date.MAX_MINUTEconstantMaximum minute supported.
date.MAX_MONTHconstantMaximum year supported.
date.MAX_SECONDSconstantMaximum seconds supported.
date.MAX_YEARconstantMaximum year supported.
date.MIN_DAYconstantMinimum day supported.
date.MIN_MONTHconstantMinimum month supported.
date.MIN_YEARconstantMinimum year supported.
date.datefunctionReturns a new Date instance representing the given system date or the current date if no argument is…
date.from_jdfunctionReturns a date instance representing the julian date.
date.from_timefunctionReturns a date object from a unix timestamp.
date.from_timezonefunctionReturns a Date from wall-clock fields understood as a local time IN the real IANA timezone name, rather…
date.gmtimefunctionReturns a dictionary representing the current time without timezone adjustment.
date.is_valid_timezonefunctionReturns true when name is a real IANA timezone identifier (e.g. 'Africa/Lagos', 'America/New_York',…
date.list_timezonesfunctionReturns every IANA timezone identifier this build’s timezone database recognizes, e.g. 'Africa/Lagos',…
date.localtimefunctionReturns a dictionary representing the current time after adjusting for the current timezone
date.mktimefunctionConvert the broken-out time into a time value with the same encoding as that of the values returned by the…
date.parsefunctionParses a date string into a Date instance, automatically detecting the format.
date.parse_formatfunctionParses a date string using an explicit format pattern and returns a Date instance.

Constants

MIN_YEAR

date.MIN_YEAR: number = 1

Minimum year supported.

MAX_YEAR

date.MAX_YEAR: number = 9999

Maximum year supported.

MIN_DAY

date.MIN_DAY: number = 1

Minimum day supported.

MAX_DAY

date.MAX_DAY: number = 31

Maximum day supported.

MIN_MONTH

date.MIN_MONTH: number = 1

Minimum month supported.

MAX_MONTH

date.MAX_MONTH: number = 12

Maximum year supported.

MAX_HOUR

date.MAX_HOUR: number = 23

Maximum hour supported.

MAX_MINUTE

date.MAX_MINUTE: number = 59

Maximum minute supported.

MAX_SECONDS

date.MAX_SECONDS: number = 59

Maximum seconds supported.

Functions

gmtime()

date.gmtime()

Returns a dictionary representing the current time without timezone adjustment.

Example,

%> echo date.gmtime()
{year: 2022, month: 3, day: 5, week_day: 6, year_day: 63, hour: 17, minute: 30, 
seconds: 55, microseconds: 620290, is_dst: false, zone: UTC, gmt_offset: 0}

Returns — dictionary

Note: year_day here is the platform’s own tm_yday, counting Jan 1st as day 0. Date.year_day counts it as day 1; the two differ by one on purpose, since this dictionary is the raw reading and Date is the module’s own representation.

localtime()

date.localtime()

Returns a dictionary representing the current time after adjusting for the current timezone

Example:

%> echo date.localtime()
{year: 2022, month: 3, day: 5, week_day: 6, year_day: 63, hour: 18, minute: 18, 
seconds: 35, microseconds: 598166, is_dst: false, zone: WAT, gmt_offset: 3600}

Returns — dictionary

mktime()

date.mktime(year, month, day, hour, minute, seconds, is_dst) -> number

Convert the broken-out time into a time value with the same encoding as that of the values returned by the time() function (that is, seconds from the Epoch, UTC) according to the timezone settings.


Example:

%> import date
%> echo date.mktime(2021, 2, 12, 13, 43, 11, false)
1613133791

Parameters

  • year (number)
  • month (number)
  • day (number)
  • hour (number)
  • minute (number)
  • seconds (number)
  • is_dst (bool)

Returns number

is_valid_timezone()

date.is_valid_timezone(name) -> bool

Returns true when name is a real IANA timezone identifier (e.g. 'Africa/Lagos', 'America/New_York', 'UTC'), backed by the timezone database embedded in this build. This is a real, complete IANA database: unlike parse()’s own timezone handling, which only recognizes UTC/GMT/Z/numeric offsets and treats every other name as an unvalidated label: so this is the function to reach for whenever a timezone name actually needs checking.

%> date.is_valid_timezone('Africa/Lagos')
true
%> date.is_valid_timezone('Neverland/Nowhere')
false

Parameters

  • name (string)

Returns bool

Raises TypeError When name is not a string.

list_timezones()

date.list_timezones() -> list[string]

Returns every IANA timezone identifier this build’s timezone database recognizes, e.g. 'Africa/Lagos', 'America/New_York', 'UTC'. There are several hundred of these; this is mainly useful for populating a picker or validating against the full set at once rather than one name at a time.

Returns list[string]

from_time()

date.from_time(time) -> Date

Returns a date object from a unix timestamp.

Example,

%> date.from_time(time()).to_string()
'<Date year: 2022, month: 3, day: 5, hour: 18, minute: 34, seconds: 1>'

Parameters

  • time (number)

Returns Date

Note: Time must be in seconds.

from_timezone()

date.from_timezone(name, year, month, day, hour, minute, seconds, is_dst) -> Date

Returns a Date from wall-clock fields understood as a local time IN the real IANA timezone name, rather than in UTC (the plain Date(...) constructor) or the process’s own system zone (mktime()). The offset, zone abbreviation, and DST state are all worked out from name’s real rules at that wall-clock moment.

A wall-clock reading can be ambiguous once a year: the hour a clock falls back repeats, e.g. 1:30am happens twice on the day America/New_York leaves daylight saving: is_dst picks which occurrence is meant, the same way it does for mktime(). A reading a clock skips entirely (the hour a clock springs forward) has no valid answer at all and raises, rather than silently returning a nearby instant.

var d = date.from_timezone('America/New_York', 2024, 7, 1, 0, 0, 0)
echo d.to_time()   # the UTC instant of 2024-07-01 00:00:00 EDT
echo d.zone        # EDT
echo d.gmt_offset  # -14400

Parameters

  • name (string) — An IANA timezone identifier.
  • year (number)
  • month (number)
  • day (number)
  • hour (number)
  • minute (number)
  • seconds (number)
  • is_dst (?bool) — Disambiguates a wall-clock reading that occurs twice; ignored otherwise. Defaults to the earlier occurrence when omitted.

Returns Date

Raises TypeError When name is not a string, or a date/time field is not a number.

Raises Error When name is not a recognized timezone, the fields are out of range, or the wall-clock reading falls in a DST gap.

from_jd()

date.from_jd(jdate) -> number

Returns a date instance representing the julian date.

Example,

%> date.from_jd(22063).to_string()
'<Date year: 2022, month: 3, day: 5, hour: 18, minute: 35, seconds: 0>'

Parameters

  • jdate (number)

Returns number

parse()

date.parse(date_string) -> Date

Parses a date string into a Date instance, automatically detecting the format.

parse recognises a broad set of standard date and datetime formats without requiring the caller to specify the format string:

Recognised formats

CategoryExamples
ISO 8601 extended2024-06-15, 2024-06-15T14:30:00Z
ISO 8601 extended2024-06-15 14:30:00+01:00
ISO 8601 compact20240615, 20240615T143000Z
RFC 2822Thu, 21 Dec 2000 16:01:07 +0200
HTTP dateSat, 05 Mar 2022 06:23:32 GMT
Full month name firstMarch 05, 2022 6:24 PM
Full month name firstJanuary 1 2000
Day-month-year21 Dec 2000 16:01:07 +0200
US slash-separated06/15/2024, 6/15/2024 2:30 PM
EU dot-separated15.06.2024, 15.06.2024 14:30:00
Hyphen numeric15-06-2024
ISO order slash2024/06/15
Time only14:30:00, 2:30 PM, 14:30:00.123456 UTC

Timezone handling

When a timezone offset is present in the string it is stored in gmt_offset (seconds) and zone (name string). When absent, zone defaults to "UTC" and gmt_offset to 0.

Ambiguity policy

For slash-separated numeric dates where both the first and second fields are ≤ 12 (e.g. 06/05/2024), the US convention is assumed: month first (MM/DD/YYYY). When the input is known to be DD/MM/YYYY, use parse_format with '%d/%m/%Y' instead.

Example

import date

var d = date.parse('2024-06-15T14:30:00Z')
echo d.year    # 2024
echo d.month   # 6
echo d.hour    # 14
echo d.zone    # UTC

var d2 = date.parse('March 05, 2022 6:24 PM')
echo d2.year   # 2022
echo d2.hour   # 18   (PM applied)

var d3 = date.parse('Thu, 21 Dec 2000 16:01:07 +0200')
echo d3.year        # 2000
echo d3.gmt_offset  # 7200

Parameters

  • date_string (string) — The date string to parse.

Returns Date

Raises TypeError When date_string is not a string.

Raises ValueError When the string cannot be parsed as a date.

parse_format()

date.parse_format(date_string, format) -> Date

Parses a date string using an explicit format pattern and returns a Date instance.

The format pattern uses the same character codes as the Date.format() method, making it straightforward to round-trip a date through format() and back through parse_format().

Format character reference

The following characters are interpreted as directives in the format string. All other characters are treated as literals and must appear verbatim in the input. Prefix a character with a backslash (\) to force literal treatment even for directive characters.

CharacterConsumesExample input
Y4-digit year2024 y
→ 1970–1999)24 mMonth with leading zero (01–12)
Month without leading zero (1–12)6 MAbbreviated month name
(case-insensitive)Jun FFull month name (case-insensitive)
June dDay with leading zero (01–31)05 j
leading zero (1–31)5 DAbbreviated weekday name (consumed and
ignored)Thu lFull weekday name (consumed and ignored)
Thursday H24-hour hour with leading zero (00–23)14 G
24-hour hour without leading zero (0–23)14 h12-hour hour with
leading zero (01–12)02 g12-hour hour without leading zero
(1–12)2 iMinutes with leading zero (00–59)
Seconds with leading zero (00–59)00 uMicroseconds (up to 6
digits)123456 vMilliseconds (up to 3 digits)
Uppercase AM/PMPM aLowercase am/pm
name/identifierUTC OTimezone offset without colon
PTimezone offset with colon+02:00 Z
seconds (signed integer)7200 cISO 8601 full datetime
(delegated to parse)2024-06-15T14:30:00+02:00 rRFC 2822 full
datetime (delegated to parse)Thu, 21 Dec 2000 16:01:07 +0200 S
Ordinal suffix (consumed and ignored)th
t,L,N,w,z,W,IOutput-only fields (skipped):

Example

import date

# Basic date
var d = date.parse_format('15/06/2024', 'd/m/Y')
echo d.year    # 2024
echo d.month   # 6
echo d.day     # 15

# DateTime with AM/PM
var d2 = date.parse_format('March 05, 2022 6:24 PM', 'F d, Y g:i A')
echo d2.hour   # 18

# Round-trip through format()
var original = date.Date(2024, 6, 15, 14, 30, 0)
var fmt      = 'D, d M Y H:i:s O'
var reparsed = date.parse_format(original.format(fmt), fmt)
echo reparsed.day    # 15
echo reparsed.month  # 6

# European DD/MM/YYYY (ambiguous with auto-detect: use parse_format)
var eu = date.parse_format('05/06/2024', 'd/m/Y')
echo eu.month  # 6
echo eu.day    # 5

# Timezone-aware
var tz = date.parse_format('2024-06-15T14:30:00+05:30', 'Y-m-d\\TH:i:sP')
echo tz.gmt_offset  # 19800 (5.5 hours in seconds)

Parameters

  • date_string (string) — The input string to parse.
  • format (string) — The format pattern describing date_string.

Returns Date

Raises TypeError When either argument is not a string.

Raises ValueError When the string does not match the expected format.

date()

date.date(year, month, day, hour, minute, seconds) -> Date

Returns a new Date instance representing the given system date or the current date if no argument is specified.

Parameters

  • year (?number)
  • month (?number)
  • day (?number)
  • hour (?number)
  • minute (?number)
  • seconds (?number)
  • is_dst (?bool)

Returns Date

Classes

Date

class date.Date

Date and Time manipulation class

A date here refers to a calendar datetime consisting of year, month, day, hour, minute and seconds.

The Date class manages both Date and DateTime and this module does not make any distinction between the two as Date is a subset of DateTime.

Example,

%> import date
%> var d = date(2021)
%> d.to_string()
'<Date year: 2021, month: 1, day: 1, hour: 0, minute: 0, seconds: 0>'
%> d = date()
%> d.to_string()
'<Date year: 2022, month: 3, day: 5, hour: 19, minute: 25, seconds: 58>'
  • printable — has a @to_string(), so echo and print() show something useful
  • serializable — has a @to_json(), so it can be handed straight to json.encode()
  • numeric — converts to a number

Constructor

date.Date(year, month, day, hour, minute, seconds, microseconds, gmt_offset, is_dst)

Parameters

  • year (?number)
  • month (?number)
  • day (?number)
  • hour (?number)
  • minute (?number)
  • seconds (?number)
  • microseconds (?number)
  • gmt_offset (?number)
  • is_dst (?bool)

Note: All arguments are optional

Note: When no argument is given, the date will be set to the current system date.

Note: when the date fields are given, the timezone is always in UTC irrespective of the system timezone or if a gmt_offset is given or not.

Note: year_day on the resulting instance counts Jan 1st as day 1, which is what to_ordinal() and format('z') expect. The raw dictionaries from localtime() and gmtime() are the one place that differs: those carry the platform’s own tm_yday, which counts Jan 1st as day 0.

Date.is_leap()

date.Date.is_leap() -> bool

Returns true if the year is a leap year or false otherwise.

Example,

%> date(2018).is_leap()
false
%> date(2020).is_leap()
true

Returns bool

Date.to_ordinal()

date.Date.to_ordinal() -> number

Returns this date’s ordinal day number in the proleptic Gregorian calendar, where day 1 is 0001-01-01. Two dates can be compared or subtracted via their ordinals to get an exact day count between them, regardless of leap years.

Example,

%> date(1, 1, 1).to_ordinal()
1
%> date(2021, 5, 11).to_ordinal()
737921

Returns number

Date.days_before_month()

date.Date.days_before_month(month) -> number

Returns the number of days between the first day of month (in this date’s own year) and this date. Positive when month is later in the year than this date, negative when earlier, zero when month is this date’s own month and day is 1.

Example,

%> date(2021, 5, 11).days_before_month(7)
51

Returns number

Date.days_before_year()

date.Date.days_before_year(year) -> number

Returns the number of days between January 1st of year and this date. Positive when year is after this date’s own year, negative when before (or the same year but earlier in it).

Example,

%> date(2021, 5, 11).days_before_year(2024)
965

Parameters

  • year (int)

Returns number

Date.days_in_month()

date.Date.days_in_month() -> number

Returns the number of days in month for the specified year.

Example,

%> date(2021, 6).days_in_month()
30

Returns number

Date.weekday()

date.Date.weekday() -> number

Returns the numbered day of the week.

Example,

%> date(2021, 5, 11).weekday()
2

Returns number

Date.week_number()

date.Date.week_number() -> number

Returns the number of the current week in the year.

Example,

%> date(2021, 5, 11).week_number()
19

Returns number

Date.format()

date.Date.format(format) -> string

Formats the current date based on the specified string

Zuri’s Date formatting table

CharacterDescriptionExample
Auppercase Ante meridian and Post meridianAM or PM a
Ante meridian and Post meridianam or pm dday of the month with
leading zero01 to 31 Dtextual representation of a day, three
lettersMon - Sun jday of the month without leading zero
lfull textual representation of the day of the weekMonday - Sunday
NISO-8601 numeric representation of the day of the week1 - 7 S
English ordinal suffix for the day of the monthst, nd, rd or th w
numeric representation of the day of the week0 - 6 zthe day of the
year (starting from 0)0 - 365 WISO-8601 week number of year, weeks
starting on MondayE.g. 33 (the 33rd week of the year) Ffull
textual representation of a monthJanuary - December mnumeric
representation of a month, with leading zeros01 - 12 nnumeric
representation of a month, without leading zeros1 - 12 Mshort
textual representation of a month, three lettersJan - Dec tnumber
of days in the given month28 - 31 Lwhether it’s a leap year
true, 0 otherwise ytwo digit representation of a yeare.g. 09 or 99
Yfull numeric representation of a year using 4 digitse.g. 2009 or
1999 h12 hour format of an hour with leading zeros01 - 12 H
hour format of an hour with leading zeros01 - 24 g12 hour format
of an hour without leading zeros1 - 12 G24 hour format of an hour
without leading zeros1 - 24 iminutes with leading zero
seconds with leading zero00 - 59 umicroseconds
millisecondse.g. 987 etimezone identifier
whether or not the date is in daylight saving time1 for true, 0
otherwise Odifference to GMT without colon between hours and minutes
e.g. +0100 Pdifference to GMT with colon between hours and minutes
e.g. +01:00 Ztimezone offset in seconds-43200 - 50400 c
8601 datee.g. 2020-03-04T15:19:21+00:00 rRFC 2822 formatted date
e.g. Thu, 21 Dec 2000 16:01:07 +0200

Example,

%> date().format('F d, Y g:i A')
'March 05, 2022 6:24 PM'

You can prevent a format character in the format string from being expanded by escaping it with a preceding backslash. If the character with a backslash is already a special sequence, you may need to also escape the backslash.

For example:

%> date().format('l jS \o\\f F Y h:i:s A')
'Wednesday 17th of May 2021 01:39:08 PM'

Parameters

  • format (string)

Returns string

Date.http()

date.Date.http() -> string

Returns the HTTP date representation of the current date.

For example,

%> date().http()
'Sat, 05 Mar 2022 06:23:32 GMT'

Returns string

Date.jd()

date.Date.jd() -> number

Converts the current date to a julian day and time.

Example,

%> date(2021, 5, 11).jd()
2459345

Returns number

Date.unix_time()

date.Date.unix_time() -> number

Returns unix mktime equivalent of the current date.

Returns number

Deprecated. Use to_time() instead as it offers more precision.

Date.to_time()

date.Date.to_time() -> number

Returns the Epoch timestamp in seconds for the given date.

Returns number

Date.clone()

date.Date.clone() -> Date

Returns an independent copy of this date.

Returns Date

Date.equals()

date.Date.equals(other) -> bool

Returns true when other is a Date representing the exact same instant in time as this one. Two dates with different gmt_offset/zone labels but the same underlying UTC instant are considered equal: the same convention Python’s timezone-aware datetime equality uses.

Parameters

  • other (any)

Returns bool

Date.diff()

date.Date.diff(other) -> number

Returns the signed difference, in seconds, between this date and other (self.to_time() - other.to_time()). Positive when this date is later than other, negative when earlier.

Parameters

  • other (Date)

Returns number

Date.add_seconds()

date.Date.add_seconds(n) -> Date

Returns a new Date, n seconds after this one (or before, if n is negative). The result keeps this date’s own gmt_offset/zone/is_dst. self is not modified.

Parameters

  • n (number)

Returns Date

Date.add_minutes()

date.Date.add_minutes(n) -> Date

Returns a new Date, n minutes after this one. See add_seconds().

Parameters

  • n (number)

Returns Date

Date.add_hours()

date.Date.add_hours(n) -> Date

Returns a new Date, n hours after this one. See add_seconds().

Parameters

  • n (number)

Returns Date

Date.add_days()

date.Date.add_days(n) -> Date

Returns a new Date, n days after this one. See add_seconds().

Parameters

  • n (number)

Returns Date

Date.add_months()

date.Date.add_months(n) -> Date

Returns a new Date, n months after this one (or before, if n is negative), keeping the same time-of-day and gmt_offset/zone/is_dst. self is not modified.

When the resulting month doesn’t have this date’s own day number (e.g. Jan 31 plus one month), the result is clamped to the last valid day of that month (Jan 31 + 1 month → Feb 28 or 29, never an overflow into March): the convention to know about, since date libraries genuinely differ on this.

Parameters

  • n (number)

Returns Date

Date.add_years()

date.Date.add_years(n) -> Date

Returns a new Date, n years after this one. See add_months() for the day-clamping rule this also follows (relevant for Feb 29 plus a non-leap number of years).

Parameters

  • n (number)

Returns Date

Date.to_offset()

date.Date.to_offset(gmt_offset, zone) -> Date

Returns a new Date representing the exact same instant as this one, re-expressed under a different gmt_offset. This is the way to convert a date from one timezone’s wall-clock reading to another’s: unlike add_seconds() and friends, which shift the underlying instant, this keeps the instant fixed and only changes how it’s displayed.

Parameters

  • gmt_offset (number) — Seconds east of UTC.
  • zone (?string) — Optional label for the new offset (e.g. 'EST'); when omitted, this date’s own zone is kept as-is.

Returns Date

Date.to_timezone()

date.Date.to_timezone(name) -> Date

Returns a new Date representing the exact same instant as this one, re-expressed under the real IANA timezone name (e.g. 'America/New_York', 'Africa/Lagos'). Unlike to_offset(), which takes the numeric offset to shift to and leaves it to the caller to already know it, this looks up name’s actual offset: correctly accounting for daylight saving: at this date’s own instant, so gmt_offset, zone, and is_dst all come out right without the caller needing to work any of that out first.

var d = date.parse('2024-07-01T00:00:00Z')
var ny = d.to_timezone('America/New_York')
echo ny.hour        # 20 (the previous day, EDT is UTC-4)
echo ny.zone        # EDT
echo ny.is_dst      # true

Parameters

  • name (string) — An IANA timezone identifier.

Returns Date

Raises TypeError When name is not a string.

Raises Error When name is not a recognized timezone (see is_valid_timezone()).

Date.to_string()

date.Date.to_string() -> string

Returns a string representation of the date

Returns string

Date.to_dict()

date.Date.to_dict() -> dict

Returns the date object as a dictionary.

Returns dict

Date.to_number()

date.Date.to_number()

2021, Richard Ore and Zuri contributors