Skip to content

Commit 458ab62

Browse files
datetime: timezone support
Closes #2886 Co-authored-by: Andrey Aksenov <[email protected]>
1 parent dbee43e commit 458ab62

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,9 @@ 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`
545+
and the :ref:`interval_arithm` sections.
524546

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

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

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

764788
* - nsec
765-
- Nanoseconds
789+
- Nanoseconds. Number.
766790

767791
* - sec
768-
- Seconds
792+
- Seconds. Number.
769793

770794
* - min
771-
- Minutes
795+
- Minutes. Number.
772796

773797
* - hour
774-
- Hours
798+
- Hours. Number.
775799

776800
* - day
777-
- Day number
801+
- Day number.
778802

779803
* - month
780-
- Month number
804+
- Month number.
781805

782806
* - year
783-
- Year
807+
- Year. Number.
784808

785809
* - wday
786-
- Days since the beginning of the week
810+
- Days since the beginning of the week. Number.
787811

788812
* - yday
789-
- Days since the beginning of the year
813+
- Days since the beginning of the year. Number.
790814

791815
* - isdst
792-
- Is the DST (Daylight saving time) applicable for the date. Boolean.
816+
- Is the DST (Daylight Saving Time) applicable for the date,
817+
see a section :ref:`timezone <timezone>`. Boolean.
793818

794819
* - tzoffset
795-
- Time zone offset from UTC
820+
- Time zone offset from UTC, see a section :ref:`timezone <timezone>`. Number.
821+
822+
* - tz
823+
- Time zone name or abbreviation, see a section :ref:`timezone <timezone>`. String.
796824

797825
:return: table with the date and time parameters
798826
:rtype: table
@@ -809,20 +837,22 @@ datetime_object
809837
day = 20,
810838
month = 8,
811839
year = 2021,
840+
tz = 'MAGT',
812841
}
813842
---
814843
...
815844
816845
tarantool> dt:totable()
817846
---
818-
- sec: 20
847+
- tz: 'MAGT'
848+
sec: 20
819849
min: 25
820850
yday: 232
821851
day: 20
822852
nsec: 0
823853
isdst: false
824854
wday: 6
825-
tzoffset: 0
855+
tzoffset: 600
826856
month: 8
827857
year: 2021
828858
hour: 18
@@ -993,6 +1023,16 @@ The matrix of the ``subtraction`` operands eligibility and their result types:
9931023
- interval
9941024
- interval
9951025

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

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