Metadata-Version: 2.1
Name: esdateutil
Version: 0.4.0
Summary: Elasticsearch datemath and dateformat parsing library. Zero dependencies
Author-email: Matthew Murr <matt@murr.dev>
License: Copyright (c) 2024 Matthew Murr
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://git.sr.ht/~murr/esdateutil
Project-URL: Repository, https://git.sr.ht/~murr/esdateutil
Project-URL: Documentation, https://git.sr.ht/~murr/esdateutil/tree/master/item/README.md
Keywords: elasticsearch,elastic,es,datemath,parser,date,format
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.3
Description-Content-Type: text/markdown
License-File: LICENSE

# esdateutil

Provides utilities for handling dates like how Elasticsearch does.

In particular:
 - Datemath parsing and evaluation ([ES Datemath Docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math))
 - Datetime string format parsing ([ES Dateformat Docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html))

The goals of this project are:
 - Be as close to Elasticsearch behaviour as Python makes sensible.
 - No mandatory runtime dependencies.
 - Customizability; most functionality should be parameterizable.

## Examples

### Basic Usage
```py
>>> from datetime import datetime
>>> datetime.now() # now is as below for all examples
datetime.datetime(2024, 9, 24, 8, 36, 17, 503027)

>>> from esdateutil import datemath, dateformat

>>> df = dateformat.DateFormat() # defaults to strict_date_optional_time||epoch_millis
>>> df.parse("2024-09-24T08:36Z") # strict_date_optional_time
datetime.datetime(2024, 9, 24, 08, 36, tzinfo=datetime.timezone.utc)
>>> df.parse("1727163377503") # epoch_millis
datetime.datetime(2024, 9, 24, 8, 36, 17, 503000)

>>> dm = DateMath()
>>> dm.eval("now-5m/h") # now minus 5 minutes rounded to the hour
datetime.datetime(2024, 9, 24, 8, 0)
>>> dm.eval("2024-09-24||-5m/h") # absolute time minus 5 minutes rounded to the hour
datetime.datetime(2024, 9, 23, 23, 0)
```

## Roadmap

This project will be version 1.0 when it provides:
 - Robust tests for weird stuff like datemath rounding on DST boundaries in 3.3, 3.5, 3.8+
 - Thread safety and tests thereof

See also the [TODO file](./TODO).

## Links

https://pypi.org/project/esdateutil/

## Building

Requires pyenv and pyenv-virtualenv to be installed on your machine.
Requires pyenv-init (pyenv and pyenv-virtualenv) to be run for pyenv local to work w/ virtualenv

## Differences from Elasticsearch

One of the consequences of using Python's built-in datetime objects and
functions by default is that they can behave very differently from version to
version and from Elasticsearch defaults. Below are some of the most important
differences in functionality to be aware of.

 - The default time resolution in Elasticsearch is milliseconds, whereas in
   Python datetime it is microseconds. This shouldn't be important unless you
   are using datemath.UNITS_ROUND_UP_MICROS or another custom round
   implementation. UNITS_ROUND_UP_MILLIS is provided as an alternative.
 - Elasticsearch has optional support for nanosecond precision - because Python
   datetimes use microsecond precision, we cannot support this completely. This
   impacts dateformat strict_date_option_time_nanos, which can still be used
   for microsecond precision instead of millis precision.
 - For custom dateformat strings we use strptime as a backup instead of [Java's time format strings](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html).

## Alternatives

### python-datemath

There is another Python project
[python-datemath](https://pypi.org/project/python-datemath/) for parsing
datemath expressions. This projects has different goals to esdateutil, the main
difference between them is that python-datemath parses a custom datemath
variant, whereas esdateutil.datemath adheres strictly to the Elasticsearch
datemath syntax. This means that although the syntax overlaps they will accept
and reject different strings.

In most cases, this probably doesn't matter. See the table below for a specific
feature difference breakdown.

| Difference          | esdateutil.datemath                                                                                                                    | python-datemath                                                                                                                                                                                                                                                                                                                |
| -----------         | ----------                                                                                                                             | ---------------                                                                                                                                                                                                                                                                                                                |
| Syntax              | Accepts and rejects same syntax as Elasticsearch. Unit chars are configurable.                                                         | Allows additional uppercase unit chars (Y for year, W for week, D for day, S for second), allows long-form units (e.g. `seconds`, `days`), allows fractional durations (e.g. +1.2d), does not allow missing number (e.g. +y vs +1y), treats expressions without anchors as having `now` (e.g. `+2d` is equivalent to `now+2d`) |
| Date String Support | Accepts the equivalent of `strict_date_optional_time\|\|epoch_millis` by default. Date parser can be overwritten by a user function.   | Accepts epoch seconds or all formats supported by arrow.get by default.                                                                                                                                                                                                                                                        |
| Date Types          | Uses Python's built-in datetime, timedelta, and timezone types for all date operations.                                                | Uses arrow's Arrow type for all operations. Supports converting to datetime.                                                                                                                                                                                                                                                   |
| Dependencies        | 0 runtime dependencies. 3 build dependencies (pytest, setuptools, wheel).                                                              | 4 runtime dependenices, including transitive dependencies: arrow --> python-dateutil --> six + types-python-dateutil. 47 build dependencies.                                                                                                                                                                                   |
| Version Support     | Supports Python 3.3+                                                                                                                   | Supports Python 3.8+ with arrow 1.0.3+. Previous versions support 2.7 and 3.x                                                                                                                                                                                                                                                  |
| Performance         | Processes 1 million datemath strings in 11.2s On My MachineTM. See profiling/ for details and to reproduce.                            | Processes 1 million datemath strings in 107.1s On My MachineTM. See profiling/ for details and to reproduce.                                                                                                                                                                                                                   |
| Type Hints          | No type hints.                                                                                                                         | Strict type checking with inline types.                                                                                                                                                                                                                                                                                        |
| Timezones           | Returns tz-unaware datetimes by default, unless tzinfo is provided in a date string or given as a timezone object arugment.            | Assumes datetimes are UTC by default, unless tz is provided in a date string or given as a string argument.                                                                                                                                                                                                                    |
| Options             | https://git.sr.ht/~murr/esdateutil/tree/master/item/esdateutil/datemath.py#L73                                                         | https://github.com/nickmaccarthy/python-datemath/blob/master/datemath/helpers.py#L85                                                                                                                                                                                                                                           |
| Logging             | Provides debug logging via the stdlib. Log level is set via the normal Python stdlib log level options.                                | Debug logging via the stdlib. Log level is set by an environment variable.                                                                                                                                                                                                                                                     |
| Licence             | MIT                                                                                                                                    | Apache 2.0                                                                                                                                                                                                                                                                                                                     |
