Skip to content

Document methods and logic of interval arithmetics in the datetime module #3082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion doc/reference/reference_lua/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,35 @@ Below is a list of the ``datetime`` module functions and methods.
* - :ref:`format() <datetime-format>`
- Convert the standard presentation of a ``datetime`` object into a formatted string.

* - :ref:`totable() <datetime-totable>`
* - :ref:`datetime_object:totable() <datetime-totable>`
- Convert the information from a ``datetime`` object into the table format.

* - :ref:`set() <datetime-set>`
- Update the field values in the existing ``datetime`` object.

* - :ref:`parse() <datetime-parse>`
- Convert an input string with the date and time information into a ``datetime`` object.

* - :ref:`add() <datetime-add>`
- Modify an existing datetime object by adding values of the input arguments.

* - :ref:`sub() <datetime-sub>`
- Modify an existing datetime object by subtracting values of the input arguments.

* - :doc:`./datetime/interval_new`
- Create an ``interval`` object from a table of time units.

* - :ref:`interval_object:totable() <interval-totable>`
- Convert the information from an ``interval`` object into the table format.

* - :doc:`./datetime/interval_arithm`
- Arithmetic operations with datetime and interval objects.

.. toctree::
:hidden:

datetime/new
datetime/datetime_object
datetime/interval_new
datetime/interval_object
datetime/interval_arithm
149 changes: 143 additions & 6 deletions doc/reference/reference_lua/datetime/datetime_object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ datetime_object

.. method:: totable()

Convert the information from the ``datetime`` object into the table format.
Convert the information from a ``datetime`` object into the table format.
Resulting table has the following fields:

.. container:: table
Expand Down Expand Up @@ -92,14 +92,14 @@ datetime_object

.. _datetime-format:

.. method:: format( ['convensions'] )
.. method:: format( ['input_string'] )

Convert the standard ``datetime`` object presentation into a formatted string.
The formatting convension specifications are the same as in the `strftime <https://www.freebsd.org/cgi/man.cgi?query=strftime&sektion=3>`__ library.
Additional convension for nanoseconds is `%f` which also allows a modifier to control the output precision of fractional part: `%5f` (see the example below).
If no arguments are set for the method, the default convensions are used: `'%FT%T.%f%z'` (see the example below).
The conversion specifications are the same as in the `strftime <https://www.freebsd.org/cgi/man.cgi?query=strftime&sektion=3>`__ library.
Additional specification for nanoseconds is `%f` which also allows a modifier to control the output precision of 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).

:param string convensions: string consisting of zero or more conversion specifications and ordinary characters
:param string input_string: string consisting of zero or more conversion specifications and ordinary characters

:return: string with the formatted date and time information
:rtype: string
Expand Down Expand Up @@ -243,3 +243,140 @@ datetime_object
- 1970-01-01T03:00:00.125+0300
...

.. _datetime-add:

.. method:: add( input[, { adjust } ] )

Modify an existing datetime object by adding values of the input argument.

:param table input: an :ref:`interval object <interval-new>` or an equivalent table (see **Example #1**)
:param string adjust: defines how to round days in a month after an arithmetic operation.
Possible values: ``none``, ``last``, ``excess`` (see **Example #2**). Defaults to ``none``.

:return: datetime_object
:rtype: cdata

**Example #1:**

.. code-block:: tarantoolsession

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 days
...

tarantool> dt:add(iv)
---
- 2021-09-02T00:00:00+0300
...

tarantool> dt:add{ day = 7 }
---
- 2021-09-09T00:00:00+0300
...

.. _datetime-add-example2:

**Example #2:**

.. code-block:: tarantoolsession

tarantool> dt = datetime.new {
day = 29,
month = 2,
year = 2020
}
---
...

tarantool> dt:add{month = 1, adjust = 'none'}
---
- 2020-03-29T00:00:00Z
...

tarantool> dt = datetime.new {
day = 29,
month = 2,
year = 2020
}
---
...

tarantool> dt:add{month = 1, adjust = 'last'}
---
- 2020-03-31T00:00:00Z
...

tarantool> dt = datetime.new {
day = 31,
month = 1,
year = 2020
}
---
...

tarantool> dt:add{month = 1, adjust = 'exсess'}
---
- 2020-03-02T00:00:00Z
...

.. _datetime-sub:

.. method:: sub( { input[, adjust ] } )

Modify an existing datetime object by subtracting values of the input argument.

:param table input: an :ref:`interval object <interval-new>` or an equivalent table (see **Example**)
:param string adjust: 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 :ref:`Example #2 <datetime-add-example2>`.

:return: datetime_object
:rtype: cdata

**Example:**

.. code-block:: tarantoolsession

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 days
...

tarantool> dt:sub(iv)
---
- 2021-08-21T00:00:00+0300
...

tarantool> dt:sub{ day = 1 }
---
- 2021-08-20T00:00:00+0300
...
95 changes: 95 additions & 0 deletions doc/reference/reference_lua/datetime/interval_arithm.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
.. _interval_arithm:

Interval arithmetic
===================

Since :doc:`2.10.0 </release/2.10.0>`.

The :doc:`datetime module </reference/reference_lua/datetime>` enables creating objects of two types: ``datetime`` and ``interval``.

If you need to shift the ``datetime`` object values, you can use either the modifier methods, that is, the :ref:`:add <datetime-add>` or :ref:`:sub <datetime-sub>` methods,
or apply interval arithmetic using overloaded `+ (__add)` or `- (__sub)` methods.

``:add``/``:sub`` modify the current object, but ``+``/``-`` create copy of the object as the operation result.

In the interval operation, each of the interval subcomponents are sequentially calculated starting 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 results of the operation exceed 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, which fields are sum of each particular component of operands.

* The result of subtraction of two intervals is similar: it's an interval object where each subcomponent is the result of subtraction of particular fields in the original operands.

* If you add datetime and interval objects, the result is a datetime object. Addition is being performed in a determined order from the largest component (``year``) to the smallest (``nsec``).

* Subtraction of two datetime objects produce an interval object. Difference of two time values is performed not as difference of the epoch seconds,
but as difference of all the subcomponents, that is, years, months, days, hours, minutes, and seconds.

* An untyped table object can be used in each context where the typed datetime or interval objects are used if left operand is typed object with overloaded operation of ``+`` or ``-``.

The matrix of the ``addition`` operands eligibility and their result types:

.. container:: table

.. list-table::
:widths: 25 25 25 25
:header-rows: 1

* -
- datetime
- interval
- table

* - **datetime**
-
- datetime
- datetime

* - **interval**
- datetime
- interval
- interval

* - **table**
-
-
-

The matrix of the ``subtraction`` operands eligibility and their result types:

.. container:: table

.. list-table::
:widths: 25 25 25 25
:header-rows: 1

* -
- datetime
- interval
- table

* - **datetime**
- interval
- datetime
- datetime

* - **interval**
-
- interval
- interval

* - **table**
-
-
-
13 changes: 9 additions & 4 deletions doc/reference/reference_lua/datetime/interval_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
datetime.interval.new()
=======================

.. function:: datetime.interval.new( [{ units }] )
.. function:: datetime.interval.new( [{ input }] )

Since :doc:`2.10.0 </release/2.10.0>`.

Create an object of the :ref:`interval type <index-box_interval>` from a table of time units.
See :ref:`description of units <interval-new-args>` and :ref:`examples <interval-new-example>` below.

:param table units: Table of :ref:`time units <interval-new-args>`. For all possible time units, the values are not restricted.
:param table input: Table with :ref:`time units and parameters<interval-new-args>`. For all possible time units, the values are not restricted.
If an empty table or no arguments are passed, the ``interval`` object with the default value ``0 seconds`` is created.

:return: :doc: interval object
:return: interval_object
:rtype: cdata

.. _interval-new-args:

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

.. container:: table

Expand Down Expand Up @@ -72,6 +72,11 @@ datetime.interval.new()
- number
- 0

* - adjust
- Defines how to round days in a month after an arithmetic operation.
- string
- 'none'

.. _interval-new-example:

**Examples:**
Expand Down
Loading