Skip to content

Commit f61f57f

Browse files
datetime: timezone support (#4429)
Closes #2886 Co-authored-by: Andrey Aksenov <38073144+andreyaksenov@users.noreply.github.com>
1 parent 6b5dbc9 commit f61f57f

File tree

1 file changed

+119
-21
lines changed

1 file changed

+119
-21
lines changed

doc/reference/reference_lua/datetime.rst

Lines changed: 119 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Below is a list of ``datetime`` functions, properties, and related objects.
5050
-
5151

5252
* - :ref:`datetime.TZ <datetime-tz>`
53-
- An array of timezone names and abbreviations
53+
- A Lua table that maps timezone names and abbreviations to its index and vice-versa.
5454

5555
* - **Methods**
5656
-
@@ -155,12 +155,14 @@ Functions
155155
- 0
156156

157157
* - tzoffset
158-
- Time zone offset from UTC, in minutes. If both ``tzoffset`` and ``tz`` are specified, ``tz`` has the preference and the ``tzoffset`` value is ignored.
158+
- A time zone offset from UTC, in minutes. If both ``tzoffset`` and
159+
``tz`` are specified, ``tz`` has the preference and the ``tzoffset``
160+
value is ignored. See a section :ref:`timezone <timezone>`.
159161
- number
160162
- 0
161163

162164
* - tz
163-
- Time zone name according to the `tz database <https://en.wikipedia.org/wiki/Tz_database>`__.
165+
- A time zone name according to the Time Zone Database. See the :ref:`timezone` section.
164166
- string
165167
- -
166168

@@ -327,7 +329,8 @@ Functions
327329
- 1970-01-01T03:00:00.125+0300
328330
...
329331
330-
tarantool> dt = datetime.parse('01:01:01', {format ='%H:%M:%S'})
332+
tarantool> dt = datetime.parse('01:01:01 MSK', {format ='%H:%M:%S %Z'})
333+
331334
---
332335
...
333336
@@ -346,6 +349,11 @@ Functions
346349
- 5
347350
...
348351
352+
tarantool> dt.tz
353+
---
354+
- MSK
355+
...
356+
349357
.. _datetime-interval-is_interval:
350358

351359
.. function:: datetime.interval.is_interval([value])
@@ -497,9 +505,21 @@ Properties
497505

498506
Since: :doc:`2.11.0 </release/2.11.0>`
499507

500-
An array of timezone names and abbreviations.
508+
A Lua table that maps timezone names (like ``Europe/Moscow``) and
509+
timezone abbreviations (like ``MSK``) to its index and vice-versa.
510+
See the :ref:`timezone` section.
511+
512+
.. code-block:: tarantoolsession
501513
514+
tarantool> datetime.TZ['Europe/Moscow']
515+
---
516+
- 947
517+
...
502518
519+
tarantool> datetime.TZ[947]
520+
---
521+
- Europe/Moscow
522+
...
503523
504524
.. _datetime-module-api-reference-objects:
505525

@@ -520,7 +540,8 @@ datetime_object
520540
.. method:: add( input[, { adjust } ] )
521541

522542
Modify an existing datetime object by adding values of the input argument.
523-
See also: :ref:`interval_arithm`.
543+
See also: :ref:`interval_arithm`. The addition is performed taking ``tzdata``
544+
into account, when ``tzoffset`` or ``tz`` fields are set, see the :ref:`timezone`.
524545

525546
:param table input: an :ref:`interval object <interval_obj>` or an equivalent table (see **Example #1**)
526547
:param string adjust: defines how to round days in a month after an arithmetic operation.
@@ -701,7 +722,8 @@ datetime_object
701722
.. method:: sub( { input[, adjust ] } )
702723

703724
Modify an existing datetime object by subtracting values of the input argument.
704-
See also: :ref:`interval_arithm`.
725+
See also: :ref:`interval_arithm`. The subtraction is performed taking ``tzdata``
726+
into account, when ``tzoffset`` or ``tz`` fields are set, see the :ref:`timezone`.
705727

706728
:param table input: an :ref:`interval object <interval_obj>` or an equivalent table (see **Example**)
707729
:param string adjust: defines how to round days in a month after an arithmetic operation.
@@ -762,37 +784,41 @@ datetime_object
762784
- Description
763785

764786
* - nsec
765-
- Nanoseconds
787+
- Nanoseconds. Number.
766788

767789
* - sec
768-
- Seconds
790+
- Seconds. Number.
769791

770792
* - min
771-
- Minutes
793+
- Minutes. Number.
772794

773795
* - hour
774-
- Hours
796+
- Hours. Number.
775797

776798
* - day
777-
- Day number
799+
- Day number.
778800

779801
* - month
780-
- Month number
802+
- Month number.
781803

782804
* - year
783-
- Year
805+
- Year. Number.
784806

785807
* - wday
786-
- Days since the beginning of the week
808+
- Days since the beginning of the week. Number.
787809

788810
* - yday
789-
- Days since the beginning of the year
811+
- Days since the beginning of the year. Number.
790812

791813
* - isdst
792-
- Is the DST (Daylight saving time) applicable for the date. Boolean.
814+
- Is the DST (Daylight Saving Time) applicable for the date,
815+
see a section :ref:`timezone <timezone>`. Boolean.
793816

794817
* - tzoffset
795-
- Time zone offset from UTC
818+
- Time zone offset from UTC, see a section :ref:`timezone <timezone>`. Number.
819+
820+
* - tz
821+
- Time zone name or abbreviation, see a section :ref:`timezone <timezone>`. String.
796822

797823
:return: table with the date and time parameters
798824
:rtype: table
@@ -809,20 +835,22 @@ datetime_object
809835
day = 20,
810836
month = 8,
811837
year = 2021,
838+
tz = 'MAGT',
812839
}
813840
---
814841
...
815842
816843
tarantool> dt:totable()
817844
---
818-
- sec: 20
845+
- tz: 'MAGT'
846+
sec: 20
819847
min: 25
820848
yday: 232
821849
day: 20
822850
nsec: 0
823851
isdst: false
824852
wday: 6
825-
tzoffset: 0
853+
tzoffset: 600
826854
month: 8
827855
year: 2021
828856
hour: 18
@@ -993,6 +1021,16 @@ The matrix of the ``subtraction`` operands eligibility and their result types:
9931021
- interval
9941022
- interval
9951023

1024+
The subtraction and addition of datetime objects are performed taking ``tzdata``
1025+
into account ``tzoffset`` or ``tz`` fields are set:
1026+
1027+
.. code-block:: tarantoolsession
1028+
1029+
tarantool> datetime.new({tz='MSK'}) - datetime.new({tz='UTC'})
1030+
---
1031+
- -180 minutes
1032+
...
1033+
9961034
.. _interval_comp:
9971035

9981036
Datetime and interval comparison
@@ -1080,10 +1118,70 @@ This section describes how the ``datetime`` module supports leap seconds:
10801118
- 1970-01-01T00:01:00Z
10811119
...
10821120
1121+
.. _timezone:
1122+
1123+
Time zones
1124+
----------
1125+
1126+
Full support has been added since :doc:`2.11.0 </release/2.11.0>`.
1127+
1128+
Tarantool uses the `Time Zone Database <https://www.iana.org/time-zones>`__
1129+
(also known as the Olson database and supported by IANA) for timezone support.
1130+
You can use the Lua module :ref:`tarantool <tarantool-module>` to get a used version of ``tzdata``.
1131+
1132+
Every datetime object has three fields that represent timezone support:
1133+
``tz``, ``tzoffset``, and ``isdst``:
1134+
1135+
* The field ``isdst`` is calculated using tzindex and attributes of the selected
1136+
timezone in the Olson DB timezone.
1137+
1138+
.. code-block:: tarantoolsession
1139+
1140+
tarantool> require('datetime').parse('2004-06-01T00:00 Europe/Moscow').isdst
1141+
---
1142+
- true
1143+
...
1144+
1145+
* The field ``tz`` field can be set to a timezone name or abbreviation. A timezone name
1146+
is a human-readable name based on the Time Zone Database, for example, "Europe/Moscow".
1147+
Timezone abbreviations represent time zones by `alphabetic abbreviations <https://www.timeanddate.com/time/zones/>`__
1148+
such as "EST", "WST", and "F". Both timezone names and abbreviations are available
1149+
via the bidirectional array :ref:`datetime.TZ <datetime-tz>`.
1150+
1151+
* The field ``tzoffset`` is calculated automatically using the current Olson rule.
1152+
This means that it takes into account summer time, leap year, and leap seconds information
1153+
when a timezone name is set. However, the ``tzoffset`` field can be set manually when
1154+
an appropriate timezone is not available.
1155+
1156+
The fields ``tz`` and ``tzoffset`` can be set in :ref:`datetime.new() <datetime-new>`,
1157+
:ref:`datetime.parse() <datetime-parse>`, and :ref:`datetime_object:set() <datetime-set>`.
1158+
The arithmetic on datetime objects are performed taking ``tzdata`` into account, when
1159+
``tzoffset`` or ``tz`` fields are set, see the :ref:`interval_arithm` section.
1160+
10831161
Limitations
10841162
-----------
10851163

1086-
The supported date range is from ``-5879610-06-22`` to ``+5879611-07-11``.
1164+
* The supported date range is from ``-5879610-06-22`` to ``+5879611-07-11``.
1165+
1166+
* There were moments in past history when local mean time in some particular zone
1167+
used a timezone offset not representable in a whole minutes but rather in seconds.
1168+
For example, in Moscow before 1918 there used to be offset +2 hours 31 minutes and 19 seconds.
1169+
See an Olson dump for this period:
1170+
1171+
.. code-block:: console
1172+
1173+
$ zdump -c1880,1918 -i Europe/Moscow
1174+
1175+
TZ="Europe/Moscow"
1176+
- - +023017 MMT
1177+
1916-07-03 00:01:02 +023119 MMT
1178+
1917-07-02 00 +033119 MST 1
1179+
1917-12-27 23 +023119 MMT
1180+
1181+
Modern ``tzdata`` rules do not use such a tiny fraction, and all timezones differ
1182+
from UTC in units measured in minutes, not seconds. Tarantool datetime module uses
1183+
minutes internally as units for ``tzoffset``. So there might be some loss of precision
1184+
if you try to operate with such ancient timestamps.
10871185

10881186
References
10891187
----------

0 commit comments

Comments
 (0)