A drop-in replacement for native datetimes that embraces UTC
Project description
****
zulu
****
|version| |travis| |coveralls| |license|
A drop-in replacement for native datetimes that embraces UTC
Links
=====
- Project: https://github.com/dgilland/zulu
- Documentation: https://zulu.readthedocs.io
- PyPI: https://pypi.python.org/pypi/zulu/
- TravisCI: https://travis-ci.org/dgilland/zulu
Features
========
- Supported on Python 2.7 and Python 3.4+
- All datetime objects converted and stored as UTC.
- Parses ISO8601 formatted strings and POSIX timestamps by default.
- Timezone representation applied only during string output formatting or when casting to native datetime object.
- Drop-in replacement for native datetime objects.
Quickstart
==========
Install using pip:
::
pip install zulu
.. code-block:: python
import zulu
zulu.now()
# <Zulu [2016-07-25T19:33:18.137493+00:00]>
dt = zulu.parse('2016-07-25T19:33:18.137493+00:00')
# <Zulu [2016-07-25T19:33:18.137493+00:00]>
dt.isoformat()
# '2016-07-25T19:33:18.137493+00:00'
dt.timestamp()
# 1469475198.137493
dt.naive
# datetime.datetime(2016, 7, 25, 19, 33, 18, 137493)
dt.datetime
# datetime.datetime(2016, 7, 25, 19, 33, 18, 137493, tzinfo=<UTC>)
dt.shift(hours=-5, minutes=10)
# <Zulu [2016-07-25T14:43:18.137493+00:00]>
dt.replace(hour=14, minute=43)
# <Zulu [2016-07-25T14:43:18.137493+00:00]>
dt.start_of('day')
# <Zulu [2016-07-25T00:00:00+00:00]>
dt.end_of('day')
# <Zulu [2016-07-25T23:59:59.999999+00:00]>
dt.span('hour')
# (<Zulu [2016-07-25T19:00:00+00:00]>, <Zulu [2016-07-25T19:59:59.999999+00:00]>)
dt.time_from(dt.end_of('day'))
# '4 hours ago'
dt.time_to(dt.end_of('day'))
# 'in 4 hours'
list(zulu.range('hour', dt, dt.shift(hours=4)))
# [Zulu [2016-07-25T19:33:18.137493+00:00]>,
# Zulu [2016-07-25T20:33:18.137493+00:00]>,
# Zulu [2016-07-25T21:33:18.137493+00:00]>,
# Zulu [2016-07-25T22:33:18.137493+00:00]>]
list(zulu.span_range('minute', dt, dt.shift(minutes=4)))
# [(Zulu [2016-07-25T19:33:00+00:00]>, Zulu [2016-07-25T19:33:59.999999+00:00]>),
# (Zulu [2016-07-25T19:34:00+00:00]>, Zulu [2016-07-25T19:34:59.999999+00:00]>),
# (Zulu [2016-07-25T19:35:00+00:00]>, Zulu [2016-07-25T19:35:59.999999+00:00]>),
# (Zulu [2016-07-25T19:36:00+00:00]>, Zulu [2016-07-25T19:36:59.999999+00:00]>)]
zulu.delta('1w 3d 2h 32m')
# <Delta [10 days, 2:32:00]>
zulu.delta('2:04:13:02.266')
# <Delta [2 days, 4:13:02.266000]>
zulu.delta('2 days, 5 hours, 34 minutes, 56 seconds')
# <Delta [2 days, 5:34:56]>
Why Zulu?
=========
Why zulu instead of `native datetimes <https://docs.python.org/3.5/library/datetime.html#datetime-objects>`_:
- Zulu has extended datetime features such as ``parse()``, ``format()``, ``shift()``, and `pytz <http://pytz.sourceforge.net/>`_ timezone support.
- Parses ISO8601 and timestamps by default without any extra arguments.
- Easier to reason about ``Zulu`` objects since they are only ever UTC datetimes.
- Clear delineation between UTC and other time zones where timezone representation is only applicable for display or conversion to native datetime.
- Supports more string parsing/formatting options using `Unicode date patterns <http://www.unicode.org/reports/tr35/tr35-19.html#Date_Field_Symbol_Table>`_ as well as ``strptime/strftime`` directives.
Why zulu instead of `Arrow <https://arrow.readthedocs.io>`_:
- Zulu is a drop-in replacement for native datetimes (inherits from ``datetime.datetime``). No need to convert using ``arrow.datetime`` when you need a datetime (zulu is always a datetime).
- Stricter parsing to avoid silent errors. For example, one might expect ``arrow.get('02/08/1987', 'MM/DD/YY')`` to fail (input does not match format) but it gladly returns ``<Arrow [2019-02-08T00:00:00+00:00)`` whereas ``zulu.parse('02/08/1987', '%m/%d/%y')`` throws ``zulu.parser.ParseError: Value "02/08/1987" does not match any format in ['%m/%d/%y']``.
- Avoids timezone/DST shifting bugs by only dealing with UTC datetimes when applying timedeltas or performing other calculations.
- Supports ``strptime/strftime`` as well as `Unicode date patterns <http://www.unicode.org/reports/tr35/tr35-19.html#Date_Field_Symbol_Table>`_ for string parsing/formatting.
Special Thanks
==============
Special thanks goes out to the authors/contributors of the following libraries that have made it possible for ``zulu`` to exist:
- `Babel <https://github.com/python-babel/babel>`_
- `iso8601 <https://bitbucket.org/micktwomey/pyiso8601>`_
- `python-dateutil <https://github.com/dateutil/dateutil>`_
- `pytimeparse <https://github.com/wroberts/pytimeparse>`_
- `pytz <http://pythonhosted.org/pytz>`_
- `tzlocal <https://github.com/regebro/tzlocal>`_
For the full documentation, please visit https://zulu.readthedocs.io.
.. |version| image:: https://img.shields.io/pypi/v/zulu.svg?style=flat-square
:target: https://pypi.python.org/pypi/zulu/
.. |travis| image:: https://img.shields.io/travis/dgilland/zulu/master.svg?style=flat-square
:target: https://travis-ci.org/dgilland/zulu
.. |coveralls| image:: https://img.shields.io/coveralls/dgilland/zulu/master.svg?style=flat-square
:target: https://coveralls.io/r/dgilland/zulu
.. |license| image:: https://img.shields.io/pypi/l/zulu.svg?style=flat-square
:target: https://pypi.python.org/pypi/zulu/
Changelog
=========
v0.4.0 (2016-08-13)
-------------------
- Rename ``zulu.DateTime`` to ``zulu.Zulu``. **breaking change**
- Rename ``Zulu.isleap`` to ``Zulu.is_leap_year``. **breaking change**
- Remove ``zulu.format`` alias (function can be accessed at ``zulu.parser.format_datetime``). **breaking change**
- Remove ``Zulu.leapdays``. **breaking change**
- Add ``Zulu.days_in_month``.
- Add ``zulu.Delta`` class that inherits from ``datetime.timedelta``.
- Add ``zulu.delta`` as alias to ``zulu.Delta.parse``.
- Add ``Zulu.time_from``, ``Zulu.time_to``, ``Zulu.time_from_now``, and ``Zulu.time_to_now`` that return "time ago" or "time to" humanized strings.
- Add ``zulu.range`` as alias to ``Zulu.range``.
- Add ``zulu.span_range`` as alias to ``Zulu.span_range``.
- Make time units (years, months, weeks, days, hours, minutes, seconds, microseconds) keyword arguments only for ``Zulu.add/subtract``, but allow positional argument to be an addable/subtractable object (datetime, timedelta, dateutil.relativedelta). **breaking change**
v0.3.0 (2016-08-03)
-------------------
- Rename ``DateTime.sub`` to ``DateTime.subtract``. **breaking change**
- Allow the first argument to ``DateTime.add`` to be a ``datetime.timedelta`` or ``dateutil.relativedelta`` object.
- Allow the first argument to ``DateTime.subtract`` to be a ``DateTime``, ``datetime.datetime``, ``datetime.timedelta``, or ``dateutil.relativedelta`` object.
- Provide ``zulu.ISO8601`` and ``zulu.TIMESTAMP`` as parse/format constants that can be used in ``zulu.parse(string, zulu.ISO8601)`` and ``DateTime.format(zulu.ISO8601)``.
- Remove special parse format string ``'timestamp'`` in favor of using just ``'X'`` as defined in ``zulu.TIMESTAMP``. **breaking change**
- Import ``zulu.parser.format`` to ``zulu.format``.
- Fix bug in ``DateTime`` addition operation that resulted in a native ``datetime`` being returned instead of ``DateTime``.
v0.2.0 (2016-08-02)
-------------------
- Add ``DateTime.datetime`` property that returns a native datetime.
- Add ``DateTime.fromgmtime`` that creates a ``DateTime`` from a UTC based ``time.struct_time``.
- Add ``DateTime.fromlocaltime`` that creates a ``DateTime`` from a local ``time.struct_time``.
- Add ``DateTime.isleap`` method that returns whether its year is a leap year.
- Add ``DateTime.leapdays`` that calculates the number of leap days between its year and another year.
- Add ``DateTime.start_of/end_of`` and other variants that return the start of end of a time frame:
- ``start/end_of_century``
- ``start/end_of_decade``
- ``start/end_of_year``
- ``start/end_of_month``
- ``start/end_of_day``
- ``start/end_of_hour``
- ``start/end_of_minute``
- ``start/end_of_second``
- Add ``DateTime.span`` that returns the start and end of a time frame.
- Add ``DateTime.span_range`` that returns a range of spans.
- Add ``DateTime.range`` that returns a range of datetimes.
- Add ``DateTime.add`` and ``DateTime.sub`` methods.
- Add ``years`` and ``months`` arguments to ``DateTime.shift/add/sub``.
- Drop support for milliseconds from ``DateTime.shift/add/sub``. **breaking change**
- Make ``DateTime.parse/format`` understand a subset of `Unicode date patterns <http://www.unicode.org/reports/tr35/tr35-19.html#Date_Field_Symbol_Table>`_.
- Set defaults for year (1970), month (1), and day (1) arguments to new ``DateTime`` objects. Creating a new ``DateTime`` now defaults to the start of the POSIX epoch.
v0.1.2 (2016-07-26)
-------------------
- Don't pin install requirements to a specific version; use ``>=`` instead.
v0.1.1 (2016-07-26)
-------------------
- Fix bug in ``DateTime.naive`` that resulted in a ``DateTime`` object being returned instead of a native ``datetime``.
v0.1.0 (2016-07-26)
-------------------
- First release.
zulu
****
|version| |travis| |coveralls| |license|
A drop-in replacement for native datetimes that embraces UTC
Links
=====
- Project: https://github.com/dgilland/zulu
- Documentation: https://zulu.readthedocs.io
- PyPI: https://pypi.python.org/pypi/zulu/
- TravisCI: https://travis-ci.org/dgilland/zulu
Features
========
- Supported on Python 2.7 and Python 3.4+
- All datetime objects converted and stored as UTC.
- Parses ISO8601 formatted strings and POSIX timestamps by default.
- Timezone representation applied only during string output formatting or when casting to native datetime object.
- Drop-in replacement for native datetime objects.
Quickstart
==========
Install using pip:
::
pip install zulu
.. code-block:: python
import zulu
zulu.now()
# <Zulu [2016-07-25T19:33:18.137493+00:00]>
dt = zulu.parse('2016-07-25T19:33:18.137493+00:00')
# <Zulu [2016-07-25T19:33:18.137493+00:00]>
dt.isoformat()
# '2016-07-25T19:33:18.137493+00:00'
dt.timestamp()
# 1469475198.137493
dt.naive
# datetime.datetime(2016, 7, 25, 19, 33, 18, 137493)
dt.datetime
# datetime.datetime(2016, 7, 25, 19, 33, 18, 137493, tzinfo=<UTC>)
dt.shift(hours=-5, minutes=10)
# <Zulu [2016-07-25T14:43:18.137493+00:00]>
dt.replace(hour=14, minute=43)
# <Zulu [2016-07-25T14:43:18.137493+00:00]>
dt.start_of('day')
# <Zulu [2016-07-25T00:00:00+00:00]>
dt.end_of('day')
# <Zulu [2016-07-25T23:59:59.999999+00:00]>
dt.span('hour')
# (<Zulu [2016-07-25T19:00:00+00:00]>, <Zulu [2016-07-25T19:59:59.999999+00:00]>)
dt.time_from(dt.end_of('day'))
# '4 hours ago'
dt.time_to(dt.end_of('day'))
# 'in 4 hours'
list(zulu.range('hour', dt, dt.shift(hours=4)))
# [Zulu [2016-07-25T19:33:18.137493+00:00]>,
# Zulu [2016-07-25T20:33:18.137493+00:00]>,
# Zulu [2016-07-25T21:33:18.137493+00:00]>,
# Zulu [2016-07-25T22:33:18.137493+00:00]>]
list(zulu.span_range('minute', dt, dt.shift(minutes=4)))
# [(Zulu [2016-07-25T19:33:00+00:00]>, Zulu [2016-07-25T19:33:59.999999+00:00]>),
# (Zulu [2016-07-25T19:34:00+00:00]>, Zulu [2016-07-25T19:34:59.999999+00:00]>),
# (Zulu [2016-07-25T19:35:00+00:00]>, Zulu [2016-07-25T19:35:59.999999+00:00]>),
# (Zulu [2016-07-25T19:36:00+00:00]>, Zulu [2016-07-25T19:36:59.999999+00:00]>)]
zulu.delta('1w 3d 2h 32m')
# <Delta [10 days, 2:32:00]>
zulu.delta('2:04:13:02.266')
# <Delta [2 days, 4:13:02.266000]>
zulu.delta('2 days, 5 hours, 34 minutes, 56 seconds')
# <Delta [2 days, 5:34:56]>
Why Zulu?
=========
Why zulu instead of `native datetimes <https://docs.python.org/3.5/library/datetime.html#datetime-objects>`_:
- Zulu has extended datetime features such as ``parse()``, ``format()``, ``shift()``, and `pytz <http://pytz.sourceforge.net/>`_ timezone support.
- Parses ISO8601 and timestamps by default without any extra arguments.
- Easier to reason about ``Zulu`` objects since they are only ever UTC datetimes.
- Clear delineation between UTC and other time zones where timezone representation is only applicable for display or conversion to native datetime.
- Supports more string parsing/formatting options using `Unicode date patterns <http://www.unicode.org/reports/tr35/tr35-19.html#Date_Field_Symbol_Table>`_ as well as ``strptime/strftime`` directives.
Why zulu instead of `Arrow <https://arrow.readthedocs.io>`_:
- Zulu is a drop-in replacement for native datetimes (inherits from ``datetime.datetime``). No need to convert using ``arrow.datetime`` when you need a datetime (zulu is always a datetime).
- Stricter parsing to avoid silent errors. For example, one might expect ``arrow.get('02/08/1987', 'MM/DD/YY')`` to fail (input does not match format) but it gladly returns ``<Arrow [2019-02-08T00:00:00+00:00)`` whereas ``zulu.parse('02/08/1987', '%m/%d/%y')`` throws ``zulu.parser.ParseError: Value "02/08/1987" does not match any format in ['%m/%d/%y']``.
- Avoids timezone/DST shifting bugs by only dealing with UTC datetimes when applying timedeltas or performing other calculations.
- Supports ``strptime/strftime`` as well as `Unicode date patterns <http://www.unicode.org/reports/tr35/tr35-19.html#Date_Field_Symbol_Table>`_ for string parsing/formatting.
Special Thanks
==============
Special thanks goes out to the authors/contributors of the following libraries that have made it possible for ``zulu`` to exist:
- `Babel <https://github.com/python-babel/babel>`_
- `iso8601 <https://bitbucket.org/micktwomey/pyiso8601>`_
- `python-dateutil <https://github.com/dateutil/dateutil>`_
- `pytimeparse <https://github.com/wroberts/pytimeparse>`_
- `pytz <http://pythonhosted.org/pytz>`_
- `tzlocal <https://github.com/regebro/tzlocal>`_
For the full documentation, please visit https://zulu.readthedocs.io.
.. |version| image:: https://img.shields.io/pypi/v/zulu.svg?style=flat-square
:target: https://pypi.python.org/pypi/zulu/
.. |travis| image:: https://img.shields.io/travis/dgilland/zulu/master.svg?style=flat-square
:target: https://travis-ci.org/dgilland/zulu
.. |coveralls| image:: https://img.shields.io/coveralls/dgilland/zulu/master.svg?style=flat-square
:target: https://coveralls.io/r/dgilland/zulu
.. |license| image:: https://img.shields.io/pypi/l/zulu.svg?style=flat-square
:target: https://pypi.python.org/pypi/zulu/
Changelog
=========
v0.4.0 (2016-08-13)
-------------------
- Rename ``zulu.DateTime`` to ``zulu.Zulu``. **breaking change**
- Rename ``Zulu.isleap`` to ``Zulu.is_leap_year``. **breaking change**
- Remove ``zulu.format`` alias (function can be accessed at ``zulu.parser.format_datetime``). **breaking change**
- Remove ``Zulu.leapdays``. **breaking change**
- Add ``Zulu.days_in_month``.
- Add ``zulu.Delta`` class that inherits from ``datetime.timedelta``.
- Add ``zulu.delta`` as alias to ``zulu.Delta.parse``.
- Add ``Zulu.time_from``, ``Zulu.time_to``, ``Zulu.time_from_now``, and ``Zulu.time_to_now`` that return "time ago" or "time to" humanized strings.
- Add ``zulu.range`` as alias to ``Zulu.range``.
- Add ``zulu.span_range`` as alias to ``Zulu.span_range``.
- Make time units (years, months, weeks, days, hours, minutes, seconds, microseconds) keyword arguments only for ``Zulu.add/subtract``, but allow positional argument to be an addable/subtractable object (datetime, timedelta, dateutil.relativedelta). **breaking change**
v0.3.0 (2016-08-03)
-------------------
- Rename ``DateTime.sub`` to ``DateTime.subtract``. **breaking change**
- Allow the first argument to ``DateTime.add`` to be a ``datetime.timedelta`` or ``dateutil.relativedelta`` object.
- Allow the first argument to ``DateTime.subtract`` to be a ``DateTime``, ``datetime.datetime``, ``datetime.timedelta``, or ``dateutil.relativedelta`` object.
- Provide ``zulu.ISO8601`` and ``zulu.TIMESTAMP`` as parse/format constants that can be used in ``zulu.parse(string, zulu.ISO8601)`` and ``DateTime.format(zulu.ISO8601)``.
- Remove special parse format string ``'timestamp'`` in favor of using just ``'X'`` as defined in ``zulu.TIMESTAMP``. **breaking change**
- Import ``zulu.parser.format`` to ``zulu.format``.
- Fix bug in ``DateTime`` addition operation that resulted in a native ``datetime`` being returned instead of ``DateTime``.
v0.2.0 (2016-08-02)
-------------------
- Add ``DateTime.datetime`` property that returns a native datetime.
- Add ``DateTime.fromgmtime`` that creates a ``DateTime`` from a UTC based ``time.struct_time``.
- Add ``DateTime.fromlocaltime`` that creates a ``DateTime`` from a local ``time.struct_time``.
- Add ``DateTime.isleap`` method that returns whether its year is a leap year.
- Add ``DateTime.leapdays`` that calculates the number of leap days between its year and another year.
- Add ``DateTime.start_of/end_of`` and other variants that return the start of end of a time frame:
- ``start/end_of_century``
- ``start/end_of_decade``
- ``start/end_of_year``
- ``start/end_of_month``
- ``start/end_of_day``
- ``start/end_of_hour``
- ``start/end_of_minute``
- ``start/end_of_second``
- Add ``DateTime.span`` that returns the start and end of a time frame.
- Add ``DateTime.span_range`` that returns a range of spans.
- Add ``DateTime.range`` that returns a range of datetimes.
- Add ``DateTime.add`` and ``DateTime.sub`` methods.
- Add ``years`` and ``months`` arguments to ``DateTime.shift/add/sub``.
- Drop support for milliseconds from ``DateTime.shift/add/sub``. **breaking change**
- Make ``DateTime.parse/format`` understand a subset of `Unicode date patterns <http://www.unicode.org/reports/tr35/tr35-19.html#Date_Field_Symbol_Table>`_.
- Set defaults for year (1970), month (1), and day (1) arguments to new ``DateTime`` objects. Creating a new ``DateTime`` now defaults to the start of the POSIX epoch.
v0.1.2 (2016-07-26)
-------------------
- Don't pin install requirements to a specific version; use ``>=`` instead.
v0.1.1 (2016-07-26)
-------------------
- Fix bug in ``DateTime.naive`` that resulted in a ``DateTime`` object being returned instead of a native ``datetime``.
v0.1.0 (2016-07-26)
-------------------
- First release.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
zulu-0.4.0.tar.gz
(34.7 kB
view hashes)
Built Distribution
zulu-0.4.0-py2.py3-none-any.whl
(20.6 kB
view hashes)