ciso8601
Fast ISO8601 date time parser for Python written in C
Rank: #1103Downloads: 11,523,461 (30 days)Stars: 574Forks: 49
Description
========
ciso8601
========
.. image:: https://img.shields.io/circleci/project/github/closeio/ciso8601.svg
:target: https://circleci.com/gh/closeio/ciso8601/tree/master
.. image:: https://img.shields.io/pypi/v/ciso8601.svg
:target: https://pypi.org/project/ciso8601/
.. image:: https://img.shields.io/pypi/pyversions/ciso8601.svg
:target: https://pypi.org/project/ciso8601/
``ciso8601`` converts `ISO 8601`_ or `RFC 3339`_ date time strings into Python datetime objects.
Since it's written as a C module, it is much faster than other Python libraries.
Tested with cPython 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14.
.. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601
.. _RFC 3339: https://tools.ietf.org/html/rfc3339
(Interested in working on projects like this? `Close`_ is looking for `great engineers`_ to join our team)
.. _Close: https://close.com
.. _great engineers: https://jobs.close.com
.. contents:: Contents
Quick start
-----------
.. code:: bash
% pip install ciso8601
.. code:: python
In [1]: import ciso8601
In [2]: ciso8601.parse_datetime('2014-12-05T12:30:45.123456-05:30')
Out[2]: datetime.datetime(2014, 12, 5, 12, 30, 45, 123456, tzinfo=pytz.FixedOffset(330))
In [3]: ciso8601.parse_datetime('20141205T123045')
Out[3]: datetime.datetime(2014, 12, 5, 12, 30, 45)
Migration to v2
---------------
Version 2.0.0 of ``ciso8601`` changed the core implementation. This was not entirely backwards compatible, and care should be taken when migrating
See `CHANGELOG`_ for the Migration Guide.
.. _CHANGELOG: https://github.com/closeio/ciso8601/blob/master/CHANGELOG.md
When should I not use ``ciso8601``?
-----------------------------------
``ciso8601`` is not necessarily the best solution for every use case (especially since Python 3.11). See `Should I use ciso8601?`_
.. _`Should I use ciso8601?`: https://github.com/closeio/ciso8601/blob/master/why_ciso8601.md
Error handling
--------------
Starting in v2.0.0, ``ciso8601`` offers strong guarantees when it comes to parsing strings.
``parse_datetime(dt: String): datetime`` is a function that takes a string and either:
* Returns a properly parsed Python datetime, **if and only if** the **entire** string conforms to the supported subset of ISO 8601
* Raises a ``ValueError`` with a description of the reason why the string doesn't conform to the supported subset of ISO 8601
If time zone information is provided, an aware datetime object will be returned. Otherwise, a naive datetime is returned.
Benchmark
---------
Parsing a timestamp with no time zone information (e.g., ``2014-01-09T21:48:00``):
.. <include:benchmark_with_no_time_zone.rst>
.. table::
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
| Module |Python 3.14|Python 3.13|Python 3.12|Python 3.11|Relative slowdown (versus ciso8601, latest Python)|…|Python 3.10|Python 3.9|Python 3.8|
+================================+===========+===========+===========+===========+==================================================+=+===========+==========+==========+
|ciso8601 |26.4 nsec |23.4 nsec |24.5 nsec |25.4 nsec |N/A |…|35.9 nsec |35.6 nsec |37 nsec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|backports.datetime_fromisoformat|N/A |N/A |N/A |N/A |0.8x |…|30.3 nsec |30.7 nsec |32 nsec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|datetime (builtin) |51.5 nsec |48 nsec |54.8 nsec |53.9 nsec |2.0x |…|N/A |N/A |N/A |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|udatetime |269 nsec |277 nsec |277 nsec |280 nsec |10.2x |…|280 nsec |279 nsec |280 nsec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|str2date |1.4 usec |1.42 usec |1.59 usec |1.59 usec |52.9x |…|1.62 usec |1.64 usec |1.76 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|pendulum |1.74 usec |65.2 nsec |64.8 nsec |64.7 nsec |65.8x |…|64.6 nsec |66.4 nsec |86.4 nsec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|iso8601 |2.13 usec |2.2 usec |2.35 usec |2.1 usec |80.6x |…|2.3 usec |2.31 usec |2.47 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|iso8601utils |N/A |N/A |N/A |N/A |61.5x |…|N/A |2.19 usec |2.51 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|isodate |2.36 usec |2.52 usec |2.78 usec |2.18 usec |89.3x |…|2.41 usec |2.4 usec |2.49 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|PySO8601 |3.55 usec |3.79 usec |3.79 usec |3.11 usec |134.6x |…|3.94 usec |3.64 usec |6.79 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|aniso8601 |4.32 usec |4.74 usec |4.95 usec |4.37 usec |163.9x |…|5.53 usec |5.19 usec |5.72 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|zulu |4.71 usec |4.63 usec |5.12 usec |4.54 usec |178.7x |…|5.17 usec |4.93 usec |5.17 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|python-dateutil |10.3 usec |11.4 usec |12.6 usec |11.9 usec |390.4x |…|14.9 usec |15.3 usec |15.8 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|arrow |13.3 usec |13.4 usec |14.7 usec |13.5 usec |503.5x |…|16.7 usec |16.2 usec |17.4 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|maya |13.7 usec |10.9 usec |14.7 usec |12.7 usec |520.0x |…|15.7 usec |14.5 usec |16 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|metomi-isodatetime |335 usec |345 usec |353 usec |359 usec |12687.0x |…|480 usec |468 usec |508 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
|moment |487 usec |502 usec |525 usec |503 usec |18471.2x |…|563 usec |559 usec |576 usec |
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
ciso8601 takes 26.4 nsec, which is **2.0x faster than datetime (builtin)**, the next fastest Python 3.14 parser in this comparison.
.. </include:benchmark_with_no_time_zone.rst>
Parsing a timestamp with time zone information (e.g., ``2014-01-09T21:48:00-05:30``):
.. <include:benchmark_with_time_zone.rst>
.. table::
+--------------------------------+-----------+-----------+-----------+-----------+--------------------------------------------------+-+-----------+----------+----------+
| Module |Python 3.14|Python 3.13|Python 3.12|Python 3.11|Relative slowdown (versus ciso8601, latest Python)|…|Python 3.10|Python 3.9|Python 3.8|
+================================+===========+===========+===========+===========+==================================================+=+===========+==========+==========+
|ciso8601