mirror of
https://github.com/kennethreitz/maya.git
synced 2026-06-05 23:00:18 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4fd8baf3eb | |||
| 5c255d2682 | |||
| 702eaab906 | |||
| 5bbe383061 | |||
| d40e698fb9 | |||
| 327f057e63 | |||
| 470516146a | |||
| dbed0555db | |||
| 2fce84195e | |||
| 7ab9e48d45 | |||
| ee1a8e2438 | |||
| b0e91d6c0e | |||
| bce5d13401 | |||
| b4a23d668d | |||
| 90051da96d | |||
| 8f0ff0d68c | |||
| fd1262a8e8 | |||
| 7558261dc8 | |||
| 1407e688fd | |||
| 0c2b936111 | |||
| 9e72ef3d2f | |||
| eabba0b79e | |||
| 8af92bc33c | |||
| 0efc489ba1 |
+94
@@ -0,0 +1,94 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
.hypothesis/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# dotenv
|
||||
.env
|
||||
|
||||
# virtualenv
|
||||
.venv/
|
||||
venv/
|
||||
ENV/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# PyCharm
|
||||
.idea/
|
||||
@@ -0,0 +1,8 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
# - "3.5" # looks like ruamel.ordereddict doesn't build for python3
|
||||
# command to install dependencies
|
||||
install: "pip install -r requirements.txt"
|
||||
# command to run tests
|
||||
script: make
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
|
||||
# Contributions to the maya project
|
||||
|
||||
## Creator & Maintainer
|
||||
|
||||
- Kenneth Reitz <me@kennethreitz.org> `@kennethreitz <https://github.com/kennethreitz>`_
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
In chronological order:
|
||||
|
||||
- Adam Nelson <adam@varud.com> (`@adamn <https://github.com/adamn>`_)
|
||||
- Timo Furrer <tuxtimo@gmail.com> (`@timofurrer <https://github.com/timofurrer>`_)
|
||||
- Moinuddin Quadri <moin18@gmail.com> (`@moin18 <https://github.com/moin18>`_)
|
||||
- Grigouze <grigouze@yahoo.fr> (`@grigouze <https://github.com/grigouze>`_)
|
||||
- Tzu-ping Chung <uranusjr@gmail.com> (`@uranusjr <https://github.com/uranusjr>`_)
|
||||
- aaronjeline (`@aaronjeline <https://github.com/aaronjeline>`_)
|
||||
- jerry2yu (`@jerry2yu <https://github.com/jerry2yu>`_)
|
||||
+23
-1
@@ -1,6 +1,16 @@
|
||||
Maya: Datetime for Humans™
|
||||
==========================
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/maya.svg
|
||||
:target: https://pypi.python.org/pypi/maya
|
||||
|
||||
.. image:: https://travis-ci.org/kennethreitz/maya.svg?branch=master
|
||||
:target: https://travis-ci.org/kennethreitz/maya
|
||||
|
||||
.. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg
|
||||
:target: https://saythanks.io/to/kennethreitz
|
||||
|
||||
|
||||
Datetimes are very frustrating to work with in Python, especially when dealing
|
||||
with different locales on different systems. This library exists to make the
|
||||
simple things **much** easier, while admitting that time is an illusion
|
||||
@@ -61,7 +71,7 @@ Behold, datetimes for humans!
|
||||
- All timezone algebra will behave identically on all machines, regardless of system locale.
|
||||
- Complete symmetric import and export of both ISO 8601 and RFC 2822 datetime stamps.
|
||||
- Fantastic parsing of both dates written for/by humans and machines (``maya.when()`` vs ``maya.parse()``).
|
||||
- Support for human slang, both import and export (e.g. `an hour ago`).
|
||||
- Support for human slang, both import and export (e.g. `an hour ago`).
|
||||
- Datetimes can very easily be generated, with or without tzinfo attached.
|
||||
- This library is based around epoch time, but dates before Jan 1 1970 are indeed supported, via negative integers.
|
||||
- Maya never panics, and always carries a towel.
|
||||
@@ -90,3 +100,15 @@ Installation is easy, with pip::
|
||||
----------
|
||||
|
||||
`Say Thanks <https://saythanks.io/to/kennethreitz>`_!
|
||||
|
||||
|
||||
How to Contribute
|
||||
-----------------
|
||||
|
||||
#. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
|
||||
#. Fork `the repository`_ on GitHub to start making your changes to the **master** branch (or branch off of it).
|
||||
#. Write a test which shows that the bug was fixed or that the feature works as expected.
|
||||
#. Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to AUTHORS_.
|
||||
|
||||
.. _`the repository`: http://github.com/kennethreitz/maya
|
||||
.. _AUTHORS: https://github.com/kennethreitz/maya/blob/master/AUTHORS.rst
|
||||
|
||||
@@ -20,7 +20,21 @@ import iso8601
|
||||
import dateutil.parser
|
||||
from tzlocal import get_localzone
|
||||
|
||||
EPOCH_START = (1970, 1, 1)
|
||||
_EPOCH_START = (1970, 1, 1)
|
||||
|
||||
|
||||
def validate_type_mayadt(func):
|
||||
"""
|
||||
Decorator to validate all the arguments to function
|
||||
are of type `MayaDT`
|
||||
"""
|
||||
def inner(*args, **kwargs):
|
||||
for arg in args + tuple(kwargs.values()):
|
||||
if not isinstance(arg, MayaDT):
|
||||
raise ValueError("Operation allowed only on object of type '{}'".format(MayaDT.__name__))
|
||||
return func(*args, **kwargs)
|
||||
return inner
|
||||
|
||||
|
||||
class MayaDT(object):
|
||||
"""The Maya Datetime object."""
|
||||
@@ -36,6 +50,35 @@ class MayaDT(object):
|
||||
"""Return's the datetime's format"""
|
||||
return format(self.datetime(), *args, **kwargs)
|
||||
|
||||
@validate_type_mayadt
|
||||
def __sub__(self, maya_dt):
|
||||
return MayaDT(self._epoch - maya_dt._epoch)
|
||||
|
||||
@validate_type_mayadt
|
||||
def __eq__(self, maya_dt):
|
||||
return self._epoch == maya_dt._epoch
|
||||
|
||||
@validate_type_mayadt
|
||||
def __ne__(self, maya_dt):
|
||||
return not self.__eq__(maya_dt)
|
||||
|
||||
@validate_type_mayadt
|
||||
def __lt__(self, maya_dt):
|
||||
return self._epoch < maya_dt._epoch
|
||||
|
||||
@validate_type_mayadt
|
||||
def __le__(self, maya_dt):
|
||||
return self.__lt__(maya_dt) or self.__eq__(maya_dt)
|
||||
|
||||
@validate_type_mayadt
|
||||
def __gt__(self, maya_dt):
|
||||
return self._epoch > maya_dt._epoch
|
||||
|
||||
@validate_type_mayadt
|
||||
def __ge__(self, maya_dt):
|
||||
return self.__gt__(maya_dt) or self.__eq__(maya_dt)
|
||||
|
||||
|
||||
# Timezone Crap
|
||||
# -------------
|
||||
|
||||
@@ -67,7 +110,7 @@ class MayaDT(object):
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=pytz.utc)
|
||||
|
||||
epoch_start = Datetime(*EPOCH_START, tzinfo=pytz.timezone('UTC'))
|
||||
epoch_start = Datetime(*_EPOCH_START, tzinfo=pytz.timezone('UTC'))
|
||||
return (dt - epoch_start).total_seconds()
|
||||
|
||||
# Importers
|
||||
@@ -104,12 +147,16 @@ class MayaDT(object):
|
||||
dt = self.datetime().astimezone(pytz.timezone(to_timezone))
|
||||
else:
|
||||
dt = Datetime.utcfromtimestamp(self._epoch)
|
||||
dt.replace(tzinfo=self._tz)
|
||||
|
||||
# Strip the timezone info if requested to do so.
|
||||
if naive:
|
||||
return dt.replace(tzinfo=None)
|
||||
else:
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=self._tz)
|
||||
|
||||
return dt.replace(tzinfo=self._tz)
|
||||
return dt
|
||||
|
||||
def iso8601(self):
|
||||
"""Returns an ISO 8601 representation of the MayaDT."""
|
||||
@@ -136,6 +183,15 @@ class MayaDT(object):
|
||||
def day(self):
|
||||
return self.datetime().day
|
||||
|
||||
@property
|
||||
def week(self):
|
||||
return self.datetime().isocalendar()[1]
|
||||
|
||||
@property
|
||||
def weekday(self):
|
||||
"""Return the day of the week as an integer. Monday is 1 and Sunday is 7"""
|
||||
return self.datetime().isoweekday()
|
||||
|
||||
@property
|
||||
def hour(self):
|
||||
return self.datetime().hour
|
||||
|
||||
@@ -29,12 +29,13 @@ required = [
|
||||
'dateparser',
|
||||
'iso8601',
|
||||
'python-dateutil',
|
||||
'ruamel.yaml'
|
||||
'ruamel.yaml',
|
||||
'tzlocal'
|
||||
]
|
||||
|
||||
setup(
|
||||
name='maya',
|
||||
version='0.1.2',
|
||||
version='0.1.5',
|
||||
description='Datetimes for Humans.',
|
||||
long_description= '\n' + read('README.rst'),
|
||||
author='Kenneth Reitz',
|
||||
|
||||
+32
-3
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
import copy
|
||||
|
||||
import maya
|
||||
|
||||
@@ -66,7 +67,7 @@ def test_print_date(capsys):
|
||||
|
||||
def test_invalid_date():
|
||||
with pytest.raises(ValueError):
|
||||
d = maya.when('another day')
|
||||
maya.when('another day')
|
||||
|
||||
|
||||
def test_slang_date():
|
||||
@@ -79,7 +80,7 @@ def test_slang_time():
|
||||
assert d.slang_time() == 'an hour ago'
|
||||
|
||||
|
||||
def test_format():
|
||||
def test_parse():
|
||||
d = maya.parse('February 21, 1994')
|
||||
assert format(d) == '1994-02-21 00:00:00+00:00'
|
||||
|
||||
@@ -89,4 +90,32 @@ def test_format():
|
||||
d = maya.parse('01/05/2016', day_first=True)
|
||||
assert format(d) == '2016-05-01 00:00:00+00:00'
|
||||
|
||||
# rand_day = maya.when('2011-02-07', timezone='US/Eastern')
|
||||
|
||||
def test_datetime_to_timezone():
|
||||
dt = maya.when('2016-01-01').datetime(to_timezone='US/Eastern')
|
||||
assert dt.tzinfo.zone == 'US/Eastern'
|
||||
|
||||
|
||||
def test_comparison_operations():
|
||||
now = maya.now()
|
||||
now_copy = copy.deepcopy(now)
|
||||
tomorrow = maya.when('tomorrow')
|
||||
|
||||
assert (now == now_copy) is True
|
||||
assert (now == tomorrow) is False
|
||||
|
||||
assert (now != now_copy) is False
|
||||
assert (now != tomorrow) is True
|
||||
|
||||
assert (now < now_copy) is False
|
||||
assert (now < tomorrow) is True
|
||||
|
||||
assert (now <= now_copy) is True
|
||||
assert (now <= tomorrow) is True
|
||||
|
||||
assert (now > now_copy) is False
|
||||
assert (now > tomorrow) is False
|
||||
|
||||
assert (now >= now_copy) is True
|
||||
assert (now >= tomorrow) is False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user