Skip to main content

A drop-in replacement for native datetimes that embraces UTC

Project description

version travis coveralls license

A drop-in replacement for native datetimes that embraces UTC

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
import zulu

zulu.now()
# <DateTime [2016-07-25T19:33:18.137493+00:00]>

dt = zulu.parse('2016-07-25T19:33:18.137493+00:00')
# <DateTime [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)
# <DateTime [2016-07-25T14:43:18.137493+00:00]>

dt.replace(hour=14, minute=43)
# <DateTime [2016-07-25T14:43:18.137493+00:00]>

dt.start_of('day')
# <DateTime [2016-07-25T00:00:00+00:00]>

dt.end_of('day')
#<DateTime [2016-07-25T23:59:59.999999+00:00]>

dt.span('hour')
# (<DateTime [2016-07-25T19:00:00+00:00]>, <DateTime [2016-07-25T19:59:59.999999+00:00]>)

list(zulu.DateTime.range('hour', dt, dt.shift(hours=4)))
# [<DateTime [2016-07-25T19:33:18.137493+00:00]>,
#  <DateTime [2016-07-25T20:33:18.137493+00:00]>,
#  <DateTime [2016-07-25T21:33:18.137493+00:00]>,
#  <DateTime [2016-07-25T22:33:18.137493+00:00]>]

list(zulu.DateTime.span_range('minute', dt, dt.shift(minutes=4)))
# [(<DateTime [2016-07-25T19:33:00+00:00]>, <DateTime [2016-07-25T19:33:59.999999+00:00]>),
#  (<DateTime [2016-07-25T19:34:00+00:00]>, <DateTime [2016-07-25T19:34:59.999999+00:00]>),
#  (<DateTime [2016-07-25T19:35:00+00:00]>, <DateTime [2016-07-25T19:35:59.999999+00:00]>),
#  (<DateTime [2016-07-25T19:36:00+00:00]>, <DateTime [2016-07-25T19:36:59.999999+00:00]>)]

Why Zulu?

Why zulu instead of native datetimes:

  • Zulu has extended datetime features such as parse(), format(), shift(), and pytz timezone support.

  • Parses ISO8601 and timestamps by default without any extra arguments.

  • Easier to reason about DateTime 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 as well as strptime/strftime directives.

Why zulu instead of Arrow:

  • 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 for string parsing/formatting.

For more details, please see the full documentation at https://zulu.readthedocs.io.

Changelog

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.

  • 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


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.2.0.tar.gz (29.3 kB view hashes)

Uploaded Source

Built Distribution

zulu-0.2.0-py2.py3-none-any.whl (16.1 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page