Tarantool CE/EE Documentation portal logo
Support
Updated at September 7, 2026   01:25 PM

Module datetime

Since: 2.10.0

The datetime module provides support for the datetime and interval data types. You can create date and time values either via the object interface or by parsing string values conforming to the ISO-8601 standard.

API Reference

Below is a list of datetime functions, properties, and related objects.

Functions

Properties

  • datetime.TZ — a Lua table that maps timezone names and abbreviations to their index and vice versa.

Methods

Functions

datetime.new([{ units }])

Create an object of the datetime type from a table of time units. See the description of units and examples below.

Parameters:

  • units (table) — Table of time units. If an empty table or no arguments are passed, the datetime object with the default values corresponding to the Unix Epoch is created: 1970-01-01T00:00:00Z.

Returns

datetime object

Return type

cdata

Possible time units for datetime.new()

Name

Description

Type

Default

nsec (usec, msec)

Fractional part of the last second. You can specify either nanoseconds (nsec), or microseconds (usec), or milliseconds (msec). Specifying two of these units simultaneously or all three of them leads to an error.

number

0

sec

Seconds. Value range: 0 - 60. A leap second is supported at the most basic level, see the section leap second.

number

0

min

Minutes. Value range: 0 - 59.

number

0

hour

Hours. Value range: 0 - 23.

number

0

day

Day number. Value range: 1 - 31. The special value -1 generates the last day of a particular month (see example below).

number

1

month

Month number. Value range: 1 - 12.

number

1

year

Year.

number

1970

timestamp

Timestamp, in seconds. Similar to the Unix timestamp, but can have a fractional part that is converted into nanoseconds in the resulting datetime object. If the fractional part of the last second is set via the nsec, usec, or msec units, the timestamp value must be an integer, otherwise an error occurs. The timestamp is not allowed if time and/or date are already set via specific units, namely, sec, min, hour, day, month, and year.

number

0

tzoffset

A time zone offset from UTC, in minutes. Value range: -720 to 840 inclusive. If both tzoffset and tz are specified, tz takes precedence and the tzoffset value is ignored. See the section timezone.

number

0

tz

A time zone name according to the Time Zone Database. See the timezone section.

string

Examples

tarantool> datetime.new {           >     nsec = 123456789,           >           >     sec = 20,           >     min = 25,           >     hour = 18,           >           >     day = 20,           >     month = 8,           >     year = 2021,           >           >     tzoffset  = 180           > }---- 2021-08-20T18:25:20.123456789+0300...tarantool> datetime.new {           >     nsec = 123456789,           >     sec = 20,           >     min = 25,           >     hour = 18,           >     day = 20,           >     month = 8,           >     year = 2021,           >     tzoffset = 60,           >     tz = 'Europe/Moscow'           > }---- 2021-08-20T18:25:20.123456789 Europe/Moscow...tarantool> datetime.new {           >     day = -1, month = 2, year = 2021,           > }---- 2021-02-28T00:00:00Z...tarantool> datetime.new {           >     timestamp = 1656664205.123, tz = 'Europe/Moscow'           > }---- 2022-07-01T08:30:05.122999906 Europe/Moscow...tarantool> datetime.new {           >     nsec = 123, timestamp = 1656664205, tz = 'Europe/Moscow'           > }---- 2022-07-01T08:30:05.000000123 Europe/Moscow...

datetime.now()

Create an object of the datetime type with the current date and time.

Returns

datetime object

Return type

cdata

datetime.is_datetime([value])

Check whether the specified value is a datetime object.

Parameters:

  • value (any) — the value to check

Returns

true if the specified value is a datetime object; otherwise, false

Return type

boolean

datetime.parse('input_string'[, {format, tzoffset}])

Convert an input string with the date and time information into a datetime object. The input string must be formatted according to one of the following standards:

  • ISO 8601
  • RFC 3339
  • extended strftime – see the description of format() for details.

By default, fields that are not specified are equal to the appropriate values of the Unix time.

Leap seconds are supported at the most basic level, see the section leap second.

Parameters:

  • input_string (string) — string with the date and time information.
  • format (string) — indicator of the input_string format. Possible values: 'iso8601', 'rfc3339', or a strptime-like format string. If no value is set, the default formatting is used ("%F %T %Z"). Note that only a part of possible ISO 8601 and RFC 3339 formats is supported. To parse unsupported formats, you can specify a format string manually using conversion specifications and ordinary characters.
  • tzoffset (number) — time zone offset from UTC, in minutes.

Returns

a datetime object

Return type

cdata

Returns

the number of parsed characters

Return type

number

Implementation details:

  • For formats with a decimal fraction of the second ([1], 5.3.1.4, a), the tail beyond 9 fractional digits is truncated.

    tarantool> datetime.parse('2024-07-31T17:30:00.123456789999', {format = 'iso8601'})---- 2024-07-31T17:30:00.123456789Z- 32...
  • For formats with a decimal fraction of the hour ([1], 5.3.1.4, c) or minute ([1], 5.3.1.4, b), the fractions are truncated to seconds precision. If second fractions are needed, the explicit representation (format a) must be used.

    tarantool> datetime.parse('2024-07-31T17,333333333', {format = 'iso8601'})---- 2024-07-31T17:19:59Z- 23...tarantool> datetime.parse('2024-07-31T17:30.333333333', {format = 'iso8601'})---- 2024-07-31T17:30:19Z- 26...

Example:

tarantool> datetime.parse('1970-01-01T00:00:00Z')---- 1970-01-01T00:00:00Z- 20...tarantool> t = datetime.parse('1970-01-01T00:00:00', {format =           > 'iso8601', tzoffset = 180})---tarantool> t---- 1970-01-01T00:00:00+0300...tarantool> t = datetime.parse('2017-12-27T18:45:32.999999-05:00',           > {format = 'rfc3339'})---tarantool> t---- 2017-12-27T18:45:32.999999-0500...tarantool> T = datetime.parse('Thu Jan 1 03:00:00 1970', {format =           > '%c'})---tarantool> T---- 1970-01-01T03:00:00Z...tarantool> T = datetime.parse('12/31/2020', {format = '%m/%d/%y'})---tarantool> T---- 2020-12-31T00:00:00Z...tarantool> T = datetime.parse('1970-01-01T03:00:00.125000000+0300',           > {format = '%FT%T.%f%z'})---tarantool> T---- 1970-01-01T03:00:00.125+0300...tarantool> dt = datetime.parse('01:01:01 MSK', {format ='%H:%M:%S %Z'})---tarantool> dt.year---- 1970...tarantool> dt.month---- 1...tarantool> dt.wday---- 5...tarantool> dt.tz---- MSK...

datetime.interval.is_interval([value])

Since: 3.2.0

Check whether the specified value is an interval object.

Parameters:

  • value (any) — the value to check

Returns

true if the specified value is an interval object; otherwise, false

Return type

boolean

Examples:

If a numeric value is passed to is_interval(), false is returned:

tarantool> datetime = require('datetime')---tarantool> datetime.interval.is_interval(123)---- false...

If an interval object is passed to is_interval(), true is returned:

tarantool> datetime.interval.is_interval(datetime.interval.new())---- true...

datetime.interval.new([{ input }])

Create an object of the interval type from a table of time units. See the description of units, and the examples below.

Parameters:

  • input (table) — Table with time units and parameters. For all possible time units, values are unrestricted. If an empty table or no arguments are passed, the interval object with the default value of 0 seconds is created.

Returns

interval_object

Return type

cdata

Possible time units and parameters for datetime.interval.new()

Name

Description

Type

Default

nsec (usec, msec)

Fractional part of the last second. You can specify either nanoseconds (nsec), or microseconds (usec), or milliseconds (msec). Specifying two of these units simultaneously or all three of them leads to an error.

number

0

sec

Seconds

number

0

min

Minutes

number

0

hour

Hours

number

0

day

Days

number

0

week

Weeks

number

0

month

Months

number

0

year

Year

number

0

adjust

Defines how to round days in a month after an arithmetic operation.

string

'none'

Examples

tarantool> datetime.interval.new()---- 0 seconds...tarantool> datetime.interval.new {           >     month = 6, year = 1           > }---- +1 years, 6 months...tarantool> datetime.interval.new {           >     day = -1           > }---- `-1 days`...

Properties

datetime.TZ

Since: 2.11.0

A Lua table that maps timezone names (for example, Europe/Moscow) and timezone abbreviations (for example, MSK) to their index and vice versa. See the timezone section.

tarantool> datetime.TZ['Europe/Moscow']---- 947...tarantool> datetime.TZ[947]---- Europe/Moscow...

Related objects

datetime_object

A datetime object.

datetime_object:add(input[, { adjust }])

Modify an existing datetime object by adding values of the input argument. See also: interval_arithm. The addition is performed taking tzdata into account, if tzoffset or tz fields are set (see timezone).

Parameters:

  • input (table) — an interval object or an equivalent table (see Example #1)
  • adjust (string) — defines how to round days in a month after an arithmetic operation. Possible values: none, last, excess (see Example #2). Defaults to none.

Returns

datetime_object

Return type

cdata

Example #1:

tarantool> dt = datetime.new {           >     day = 26,           >     month = 8,           >     year = 2021,           >     tzoffset  = 180           > }---tarantool> iv = datetime.interval.new {day = 7}---tarantool> dt, iv---- 2021-08-26T00:00:00+0300- +7 daystarantool> dt:add(iv)---- 2021-09-02T00:00:00+0300tarantool> dt:add{ day = 7 }---- 2021-09-09T00:00:00+0300

Example #2

tarantool> dt = datetime.new {           >     day = 29,           >     month = 2,           >     year = 2020           > }---tarantool> dt:add{month = 1, adjust = 'none'}---- 2020-03-29T00:00:00Ztarantool> dt = datetime.new {           >     day = 29, month = 2, year = 2020           > }---tarantool> dt:add{month = 1, adjust = 'last'}---- 2020-03-31T00:00:00Ztarantool> dt = datetime.new {           >     day = 31, month = 1, year = 2020           > }---tarantool> dt:add{month = 1, adjust = 'excess'}---- 2020-03-02T00:00:00Z

datetime_object:format(['input_string'])

Convert the standard datetime object presentation into a formatted string. The conversion specifications are the same as in the strftime function. An additional specification for nanoseconds is %f, which also allows using a modifier to control the output precision of the fractional part: %5f (see the example below). If no arguments are set for the method, the default conversions are used: '%FT%T.%f%z' (see the example below).

Parameters:

  • input_string (string) — a string consisting of zero or more conversion specifications and ordinary characters

Returns

a string with the formatted date and time information

Return type

string

Example:

tarantool> dt = datetime.new {           >     nsec = 123456789,           >           >     sec = 20,           >     min = 25,           >     hour = 18,           >           >     day = 20,           >     month = 8,           >     year = 2021,           >           >     tzoffset  = 180           > }---tarantool> dt:format('%d.%m.%y %H:%M:%S.%5f')---- 20.08.21 18:25:20.12345tarantool> dt:format()---- 2021-08-20T18:25:20.123456789+0300tarantool> dt:format('%FT%T.%f%z')---- 2021-08-20T18:25:20.123456789+0300

datetime_object:set([{ units }])

Update the field values in the existing datetime object.

Parameters:

  • units (table) — a table of time units. The time units are the same as for the datetime.new() function.

Returns

updated datetime_object

Return type

cdata

Example:

tarantool> dt = datetime.new {           >     nsec = 123456789,           >           >     sec = 20,           >     min = 25,           >     hour = 18,           >           >     day = 20,           >     month = 8,           >     year = 2021,           >           >     tzoffset  = 180           > }---tarantool> dt:set {msec = 567}---- 2021-08-20T18:25:20.567+0300tarantool> dt:set {tzoffset = 60}---- 2021-08-20T18:25:20.567+0100

datetime_object:sub({ input[, adjust] })

Modify an existing datetime object by subtracting values of the input argument. See also: interval_arithm. The subtraction is performed taking tzdata into account, if tzoffset or tz fields are set (see timezone).

Parameters:

  • input (table) — an interval object or an equivalent table (see Example)
  • adjust (string) — defines how to round days in a month after an arithmetic operation. Possible values: none, last, excess. Defaults to none. The logic is similar to the one of the :add() method – see Example #2.

Returns

datetime_object

Return type

cdata

Example:

tarantool> dt = datetime.new {           >     day = 26,           >     month = 8,           >     year = 2021,           >     tzoffset  = 180           > }---tarantool> iv = datetime.interval.new {day = 5}---tarantool> dt, iv---- 2021-08-26T00:00:00+0300- +5 daystarantool> dt:sub(iv)---- 2021-08-21T00:00:00+0300tarantool> dt:sub{ day = 1 }---- 2021-08-20T00:00:00+0300

datetime_object:totable()

Convert the information from a datetime object into the table format. The resulting table has the following fields:

Field name

Description

nsec

Nanoseconds. Number.

sec

Seconds. Number.

min

Minutes. Number.

hour

Hours. Number.

day

Day number.

month

Month number.

year

Year. Number.

wday

Days since the beginning of the week. Number. 1 is Sunday, as for os.date('*t').

yday

Days since the beginning of the year. Number.

timestamp

Timestamp, in seconds. Number.

isdst

Whether the DST (Daylight Saving Time) is applicable for the date, see the timezone section. Boolean.

tzoffset

Time zone offset from UTC, see the timezone section. Number.

tz

Time zone name or abbreviation, see the timezone section. String.

Returns

a table with date and time parameters

Return type

table

Example:

tarantool> dt = datetime.new {           >     sec = 20,           >     min = 25,           >     hour = 18,           >           >     day = 20,           >     month = 8,           >     year = 2021,           >     tz = 'MAGT',           > }---tarantool> dt:totable()---- tz: 'MAGT'  sec: 20 min: 25 yday: 232 day: 20 nsec: 0 isdst: false wday: 6  tzoffset: 600 month: 8 year: 2021 hour: 18

interval_object

An interval object.

interval_object:totable()

Convert the data from an interval object into the table format. The resulting table has the following fields:

Field name

Description

nsec

Nanoseconds

sec

Seconds

min

Minutes

hour

Hours

day

Day number

month

Month number

year

Year

week

Week number

adjust

Defines how to round days in a month after an arithmetic operation.

Returns

a table with date and time parameters

Return type

table

Example:

tarantool> iv = datetime.interval.new{month = 1, adjust = 'last'}---tarantool> iv:totable()---- adjust: last  sec: 0 nsec: 0 day: 0 week: 0 hour: 0 month: 1 year: 0 min: 0

Datetime and interval arithmetic

The datetime module allows creating objects of two types: datetime and interval.

If you need to shift the values of a datetime object, you can use the modifier methods, that is, datetime_object:add() or datetime_object:sub(), or apply interval arithmetic using the overloaded + (__add) or - (__sub) operators.

The datetime_object:add()/datetime_object:sub() methods modify the current object, while the +/- operators create a copy of the object as the operation result.

When an interval operation is performed, each of the interval subcomponents is calculated sequentially from the largest (year) to the smallest (nsec):

  • year – years
  • month – months
  • week – weeks
  • day – days
  • hour – hours
  • min – minutes
  • sec – seconds
  • nsec – nanoseconds

If the result of the operation exceeds the allowed range for any of the components, an exception is raised.

The datetime and interval objects can participate in arithmetic operations:

  • The sum of two intervals is an interval object whose fields are the sum of each particular component of the operands.
  • The result of subtracting two intervals is similar: it is an interval object where each subcomponent is the result of subtracting the corresponding fields of the original operands.
  • Adding a datetime and an interval object produces a datetime object. The addition is performed in a determined order – from the largest component (year) to the smallest (nsec).
  • Subtracting two datetime objects produces an interval object. The difference between two time values is calculated not as the difference of epoch seconds, but as the difference of all the subcomponents, that is, years, months, days, hours, minutes, and seconds.
  • An untyped table object can be used in any context where typed datetime or interval objects are used, if the left operand is a typed object with an overloaded + or - operation.

The matrix of eligible operands for addition and their result types:

datetime

interval

table

datetime

unsupported

datetime

datetime

interval

datetime

interval

interval

The matrix of eligible operands for subtraction and their result types:

datetime

interval

table

datetime

interval

datetime

datetime

interval

unsupported

interval

interval

Addition and subtraction of datetime objects are performed taking tzdata into account, if tzoffset or tz fields are set:

tarantool> datetime.new({tz='MSK'}) - datetime.new({tz='UTC'})---- -180 minutes

Datetime and interval comparison

If you need to compare the values of datetime and interval objects, you can use the standard Lua relational operators: ==, ~=, >, <, >=, and <=. These operators use the overloaded __eq, __lt, and __le metamethods to compare values.

Support for relational operators for interval objects has been added since 2.11.0.

Example 1:

tarantool> dt1 = datetime.new({ year = 2010 })---tarantool> dt2 = datetime.new({ year = 2024 })---tarantool> dt1 == dt2---- falsetarantool> dt1 < dt2---- true

Example 2:

tarantool> iv1 = datetime.interval.new({month = 1})---tarantool> iv2 = datetime.interval.new({month = 2})---tarantool> iv1 < iv2---- true

Leap second

Leap seconds are a periodic one-second adjustment of Coordinated Universal Time (UTC) in order to keep the system time of day close to the mean solar time. However, the Earth's rotation speed varies in response to climatic and geological events, and due to this, UTC leap seconds are irregularly and unpredictably spaced.

Tarantool includes the Time Zone Database that besides the timezone description files also contains a leap seconds file. You can use the Lua module tarantool to get a used version of tzdata.

The datetime module supports leap seconds at the most basic level:

  • The datetime.parse() function correctly parses an input string with 60 seconds:

    tarantool> datetime.parse('23:12:60', {format ='%H:%M:%S'})---- 1970-01-01T23:13:00Z- 8...
  • The datetime.new() function and the datetime_object:set() method accept a table with the sec key set to 60 seconds:

    tarantool> datetime.new({ sec = 60 })---- 1970-01-01T00:01:00Z...

Meanwhile, the following cases are NOT supported by the datetime module:

  • With the datetime.new() function, 60 leap seconds in the sec key add an extra minute like regular seconds, and the result is represented in a regular manner, without leap seconds:

    tarantool> datetime.new({ year = 1998, month = 12, day = 31, hour = 23, min = 59, sec = 60})---- 1999-01-01T00:00:00Z...
  • The datetime.parse() function returns an error when parsing an input string with a leap second (60 seconds) and a format that supports leap seconds ('rfc3339', 'iso8601'):

    tarantool> datetime.parse('1998-12-31T23:59:60Z', {format='rfc3339'})---- error: 'builtin/datetime.lua:885: could not parse  ''1998-12-31T23:59:60Z'''...

Time zones

Full support has been added since version 2.11.0.

Tarantool uses the Time Zone Database (also known as the Olson database and supported by IANA) for timezone support. You can use the Lua module tarantool to get a used version of tzdata.

Every datetime object has three fields related to timezone support: tz, tzoffset, and isdst:

  • The isdst field is calculated using tzindex and attributes of the selected timezone from the Olson database.

    tarantool> require('datetime').parse('2004-06-01T00:00 Europe/Moscow').isdst---- true...
  • The tz field can take a timezone name or abbreviation. A timezone name is a human-readable name based on the Time Zone Database, for example, "Europe/Moscow". Timezone abbreviations represent time zones as alphabetic abbreviations such as "EST", "WST", and "F". Both timezone names and abbreviations are available via the bidirectional array datetime.TZ.

  • The tzoffset field is calculated automatically using the current Olson rule. This means that, for a given timezone name, information about summer time, leap years, and leap seconds is taken into account. However, the tzoffset field can be set manually if a suitable timezone is not available. The tz and tzoffset fields can be set in datetime.new(), datetime.parse(), and datetime_object:set(). Arithmetic operations on datetime objects are performed taking tzdata into account, if tzoffset or tz fields are set (see the section interval_arithm).

Limitations

  • The supported date range is from -5879610-06-22 to +5879611-07-11.

  • There were periods in history when the local mean time in some timezones used an offset expressed not in whole minutes but in seconds. For example, in Moscow before 1918 the offset used was +2 hours 31 minutes 19 seconds. See an Olson dump for this period:

    $ zdump -c1880,1918 -i Europe/MoscowTZ="Europe/Moscow"- +023017 MMT 1916-07-03 00:01:02 +023119 MMT 1917-07-02 00 +033119 MST 1 1917-12-27 23 +023119 MMT

    Modern tzdata rules do not use such tiny fractions, and all timezones differ from UTC by a value that is a multiple of minutes, not seconds. The datetime module in Tarantool uses minutes internally as units for tzoffset. So there might be some loss of precision when working with such old timestamps.

References