Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
zulu
|version| |build| |coveralls| |license|
A drop-in replacement for native datetimes that embraces UTC
Install using pip:
::
pip3 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 = zulu.create(2016, 7, 25, 19, 33, 18, 137493)
# <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.format('%Y-%m-%d')
# 2016-07-25
dt.format('YYYY-MM-dd')
# 2016-07-25
dt.format("E, MMM d, ''YY")
# "Mon, Jul 25, '16"
dt.format("E, MMM d, ''YY", locale='de')
# "Mo., Juli 25, '16"
dt.format("E, MMM d, ''YY", locale='fr')
# "lun., juil. 25, '16"
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.parse_delta('1w 3d 2h 32m')
# <Delta [10 days, 2:32:00]>
zulu.parse_delta('2:04:13:02.266')
# <Delta [2 days, 4:13:02.266000]>
zulu.parse_delta('2 days, 5 hours, 34 minutes, 56 seconds')
# <Delta [2 days, 5:34:56]>
Why zulu instead of native datetimes <https://docs.python.org/3.5/library/datetime.html#datetime-objects>
_:
parse()
, format()
, shift()
, and python-dateutil
_ timezone support.Zulu
objects since they are only ever UTC datetimes.Unicode date patterns
_ as well as strptime/strftime
directives.Why zulu instead of Arrow
_:
datetime.datetime
). No need to convert using arrow.datetime
when you need a datetime (zulu is always a datetime).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']
.strptime/strftime
as well as Unicode date patterns
_ for string parsing/formatting.Special thanks goes out to the authors/contributors of the following libraries that have made it possible for zulu
to exist:
Babel
_iso8601
_python-dateutil
_pytimeparse
_pytz
_For the full documentation, please visit https://zulu.readthedocs.io.
.. _Unicode date patterns: http://www.unicode.org/reports/tr35/tr35-19.html#Date_Field_Symbol_Table .. _Arrow: https://arrow.readthedocs.io .. _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
.. |version| image:: https://img.shields.io/pypi/v/zulu.svg?style=flat-square :target: https://pypi.python.org/pypi/zulu/
.. |build| image:: https://img.shields.io/github/actions/workflow/status/dgilland/zulu/main.yml?branch=master&style=flat-square :target: https://github.com/dgilland/zulu/actions
.. |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/
datetime.utcnow
and datetime.utcfromtimestamp
.Zulu.time_from
, Zulu.time_to
, Zulu.time_from_now
, and Zulu.time_to_now
where keyword arguments weren't passed to underlying Delta.format
call.Zulu.format
where "YY" and "YYYY" format patterns would return the year in "Week of Year" based calendars instead of the regular calendar year.'week'
option to Zulu.start_of
, Zulu.end_of
, Zulu.span
, and Zulu.span_range
. Thanks ThomasChiroux_!Zulu.astimezone
in Python 3.8 due to change in return type from super().asdatetime
. In Python<=3.7, super().asdatetime
returned as instance of datetime
, but in Python 3.8 another instance of Zulu
was returned instead. Zulu.astimezone
will now return a datetime
instance in Python 3.8.zulu.Timer.__init__()
.fold
attribute support to Zulu
.zulu.to_seconds
for converting units of time to total number of seconds.zulu.Timer
class that can be used to track elapsed time (like a stopwatch) or as a countdown timer.Zulu.datetimetuple()
.Zulu.datetuple()
.Zulu.__iter__
method. (breaking change)Delta.__iter__
method. (breaking change)Add Python 3.6 support.
Add Delta.__iter__
method that yields 2-element tuples like Zulu.__iter__
. Delta values are normalized into integer values distributed from the higher units to the lower units.
Add Delta.__float__
and Delta.__int__
methods for converting to seconds.
Add Zulu.__float__
and Zulu.__int__
methods for converting to epoch seconds.
Fix issue in Python 3.6 where zulu.now()
returned a naive datetime Zulu
instance.
Make Zulu.__iter__
yield 2-element tuples containing (unit, value)
like (('year', 2000), ('month', 12), ...)
so it can be converted to a dict
with proper keys easier. (breaking change)
Remove previously deprecated zulu.delta()
function. Use zulu.parse_delta()
instead. (breaking change)
Rename modules: (breaking change)
zulu.datetime -> zulu.zulu
zulu.timedelta -> zulu.delta
locale
in Delta.format()
when a locale is not known via environment variables.zulu.parse_delta
as alias for Delta.parse
.zulu.delta
in favor of zulu.parse_delta
.Zulu()
, Zulu.parse()
, and zulu.parse()
to be a dict
containing keys corresponding to initialization parameters.python-dateutil>=2.6.0
. (breaking change)pytz
timezone handling for strings with dateutil.tz.gettz
. Continue to support pytz
timezones during Zulu()
object creation. (breaking change).dateutil.tz.tzutc()
. Was previously pytz.UTC
. (breaking change)dateutil.tz.tzlocal()
. Was previously set by the tzlocal
library. (breaking change)Add comparison methods to Zulu
:
is_before
is_on_or_before
is_after
is_on_or_after
is_between
Zulu()
constructor by eliminating multiple unnecessary calls to datetime
constructor.Zulu
not being pickle-able.Add missing magic method overrides for Delta
for +delta
, -delta
, and abs(delta)
so that Delta
is returned instead of datetime.timedelta
.
__pos__
__neg__
__abs__
Make Zulu.__sub__
and Zulu.subtract
return a Delta
object instead of datetime.timedelta
.
Make zulu.delta
and Zulu.Delta.parse
accept a number.
Allow the first argument to Zulu.shift
be a timedelta or relative delta object.
Ensure that mathematical magic methods for Delta
return Delta
objects and not datetime.timedelta
.
__add__
__radd__
__sub__
__mul__
__rmul__
__floordiv__
__truediv__
(Python 3 only)__div__
(Python 2 only)__mod__
(Python 3 only)__divmod__
(Python 3 only)format_datetime
. breaking changeX
and XX
. breaking changeX
to timestamp
. breaking changezulu.create
as factory function to create a zulu.Zulu
instance.Zulu.format
when using Unicode date pattern format tokens.Delta.format
.Delta.format
. Locale is currently not supported in Zulu.format
so decided to disable it in Delta.format
until both can have it. breaking changezulu.DateTime
to zulu.Zulu
. breaking changeZulu.isleap
to Zulu.is_leap_year
. breaking changezulu.format
alias (function can be accessed at zulu.parser.format_datetime
). breaking changeZulu.leapdays
. breaking changeZulu.days_in_month
.zulu.Delta
class that inherits from datetime.timedelta
.zulu.delta
as alias to zulu.Delta.parse
.Zulu.time_from
, Zulu.time_to
, Zulu.time_from_now
, and Zulu.time_to_now
that return "time ago" or "time to" humanized strings.zulu.range
as alias to Zulu.range
.zulu.span_range
as alias to Zulu.span_range
.Zulu.add/subtract
, but allow positional argument to be an addable/subtractable object (datetime, timedelta, dateutil.relativedelta). breaking changeDateTime.sub
to DateTime.subtract
. breaking changeDateTime.add
to be a datetime.timedelta
or dateutil.relativedelta
object.DateTime.subtract
to be a DateTime
, datetime.datetime
, datetime.timedelta
, or dateutil.relativedelta
object.zulu.ISO8601
and zulu.TIMESTAMP
as parse/format constants that can be used in zulu.parse(string, zulu.ISO8601)
and DateTime.format(zulu.ISO8601)
.'timestamp'
in favor of using just 'X'
as defined in zulu.TIMESTAMP
. breaking changezulu.parser.format
to zulu.format
.DateTime
addition operation that resulted in a native datetime
being returned instead of DateTime
.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.
>=
instead.DateTime.naive
that resulted in a DateTime
object being returned instead of a native datetime
... _ThomasChiroux: https://github.com/ThomasChiroux
MIT License
Copyright (c) 2020 Derrick Gilland
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.
FAQs
A drop-in replacement for native datetimes that embraces UTC
We found that zulu demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.