# date

The `date` module provides various utilities to handle date and time operations
within the Cypher Query Language. These functions can be used in conjunction
with other Cypher expressions to handle date-related tasks such as formatting,
parsing, comparisons, and arithmetic, thus enhancing the capabilities of
Memgraph for managing time-based data.

| Trait               | Value               |
| ------------------- | ------------------- |
| **Module type**     | util                |
| **Implementation**  | Python              |
| **Parallelism**     | sequential          |

## Procedures

### `format()`

Returns a string representation of time value using the specified unit,
specified format, and specified timezone.

#### Input:

- `time: int` ➡ Time passed since the Unix epoch.
- `unit: string (default="ms")` ➡ The unit of the given time.
- `format: string (default="%Y-%m-%d %H:%M:%S %Z")` ➡ The pattern to be formatted to.
- `timezone: string (default="UTC")` ➡ The timezone to be used.

The `unit` parameter supports the following values:
- "ms" for milliseconds
- "s" for seconds
- "m" for minutes
- "h" for hours
- "d" for days

The `format` parameter supports values defined under [Python strftime format
codes](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).

The `timezone` parameter can be specified with the database TZ identifier (text)
name, as listed for
[timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).

> **Warning**
>
> Starting with `tzdata` version `2024b`, its format has changed and an
> incompatibility with the current libstdc++ has been introduced. As a result,
> using `tzdata` version `2024b` or later will break the timezone feature in
> Memgraph. This could lead to incorrect handling of timezones and unexpected
> behavior in your application. To avoid compatibility issues, please ensure that
> you are using `tzdata` `v2024a` or earlier with Memgraph until libstdc++ has
> been updated to support the new format in tzdata.

#### Output:

- `formatted: string` ➡ The received time in the specified format.

#### Usage:

Use the following query to get a string representation from a time value:

```cypher
CALL date.format(74976, "h", "%Y/%m/%d %H:%M:%S %Z", "Mexico/BajaNorte")
YIELD formatted RETURN formatted;
```

```plaintext
+-------------------------------+
| formatted                     |
+-------------------------------+
| "1978/07/21 17:00:00 PDT"     |
+-------------------------------+
```

### `parse()`

Parses the date string using the specified format and specified timezone into
the specified time unit.

#### Input:

- `time: string` ➡ A datetime.
- `unit: string (default="ms")` ➡ The unit to be parsed to.
- `format: string (default="%Y-%m-%d %H:%M:%S")` ➡ The format of the given DateTime.
- `timezone: string (default="UTC")` ➡ The timezone to be used.

The `unit` parameter supports the following values:
- "ms" for milliseconds
- "s" for seconds
- "m" for minutes
- "h" for hours
- "d" for days

The `format` parameter supports values defined under [Python strftime format
codes](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).

The `timezone` parameter can be specified with the database TZ identifier (text)
name, as listed for
[timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).

> **Warning**
>
> Starting with `tzdata` version `2024b`, its format has changed and an
> incompatibility with the current libstdc++ has been introduced. As a result,
> using `tzdata` version `2024b` or later will break the timezone feature in
> Memgraph. This could lead to incorrect handling of timezones and unexpected
> behavior in your application. To avoid compatibility issues, please ensure that
> you are using `tzdata` `v2024a` or earlier with Memgraph until libstdc++ has
> been updated to support the new format in tzdata.

#### Output:

- `parsed: int` ➡ The number of time units that have elapsed since the Unix epoch.

#### Usage:

Use the following query to parse the date string:

```cypher
CALL date.parse("2023/08/03 14:30:00", "h", "%Y/%m/%d %H:%M:%S", "Europe/Zagreb")
YIELD parsed RETURN parsed;
```

```plaintext
+---------------------+
| parsed              |
+---------------------+
| 469740              |
+---------------------+
```

## Functions

### `add()`

Adds two numeric values representing quantities of time in specific units.

#### Input:

- `time: int` ➡ The first term in the addition operation.
- `unit: string` ➡ The time unit of the above value.
- `add_value: int` ➡ The second term in the addition operation.
- `add_unit: string` ➡ The time unit of the above value.

The `unit` parameter supports the following values:
- "ms", "milli", "millis" and "milliseconds" for milliseconds
- "s", "second" and "seconds" for seconds
- "m", "minute" and "minutes" for minutes
- "h", "hour" and "hours" for hours
- "d", "day" and "days" for days

#### Output:

The output of this function is an `int` value representing the total time
expressed in the time unit of the first parameter.

#### Usage:

```cypher
RETURN date.add(100, "day", 24, "h") AS sum;
```

```plaintext
+---------------------+
| sum                 |
+---------------------+
| 101                 |
+---------------------+
```

### `convert_format()`

Converts a string containing a date or time in one specified format into a
string of another specified date or time format.

> **Info**
>
> This function is equivalent to **apoc.date.convertFormat**.

#### Input:

- `temporal: string` ➡ The date to be converted.
- `currentFormat: string` ➡ The format of the input `temporal` string date.
- `convertTo: string` ➡ The required output date string format.

`conert_format` supports the following formats for both `currentFormat` and
`convertTo`:

- `basic_iso_date` - `YYYYMMDD` (e.g., `20111203`)
- `iso_local_date` - `YYYY-MM-DD` (e.g., `2011-12-03`)
- `iso_offset_date` - `YYYY-MM-DD±hh:mm` (e.g., `2011-12-03+01:00`)
- `iso_date` - `YYYY-MM-DD` or `YYYY-MM-DD±hh:mm` (e.g., `2011-12-03+01:00`)
- `iso_local_time` - `HH:MM:SS` (e.g., `10:15:30`)
- `iso_offset_time` - `HH:MM:SS±hh:mm` (e.g., `10:15:30+01:00`)
- `iso_time` - `HH:MM:SS` or `HH:MM:SS±hh:mm` (e.g, `10:15:30+01:00`)
- `iso_local_date_time` - `YYYY-MM-DDTHH:MM:SS` (e.g., `2011-12-03T10:15:30`)
- `iso_offset_date_time` - `YYYY-MM-DDTHH:MM:SS±hh:mm` (e.g., `2011-12-03T10:15:30+01:00`)
- `iso_zoned_date_time` - `YYYY-MM-DDTHH:MM:SS±hh:mm[ZoneName]` (e.g., `2011-12-03T10:15:30+01:00[Europe/Paris]`)
- `iso_date_time` - `YYYY-MM-DDTHH:MM:SS±hh:mm[ZoneName]` (e.g, `2011-12-03T10:15:30+01:00[Europe/Paris]`)

#### Output:

The output of this function is a `string` value representing the `temporal` input
expressed in the required `convertTo` format.

#### Usage:

```cypher
RETURN date.convert_format('2011-12-03T10:15:30+01:00[Europe/Paris]', 'iso_zoned_date_time', 'iso_offset_date_time') AS dt;
```

```plaintext
+-----------------------------+
| dt                          |
+-----------------------------+
| "2011-12-03T10:15:30+01:00" |
+-----------------------------+
```
