Compare commits

...

70 Commits

Author SHA1 Message Date
kennethreitz 450dff000b v0.1.8 2017-02-09 21:29:03 -05:00
kennethreitz 90ba4ded70 fix for rand-day 2017-02-09 21:28:40 -05:00
kennethreitz 2e33ede5ac document add 2017-02-09 21:28:27 -05:00
kennethreitz 6a9661759f fix add/subtract 2017-02-09 21:28:22 -05:00
kennethreitz f46c3792e8 pipfile.lock 2017-02-09 21:23:37 -05:00
kennethreitz c07e51bf4d Update README.rst 2017-02-09 20:54:51 -05:00
kennethreitz 63d5e0ce90 Subtract and add! 2017-02-09 20:43:55 -05:00
kennethreitz 361f7a45ad Merge pull request #51 from sdispater/improve-iso8601-parsing
Improve iso8601 parsing
2017-02-09 19:15:19 -06:00
Sébastien Eustace 09db746027 Updates AUTHORS.rst 2017-02-09 19:40:09 -05:00
Sébastien Eustace 15a447491a Improves ISO8601 parsing 2017-02-09 19:39:18 -05:00
kennethreitz f8d83c0370 Update README.rst 2017-02-09 17:19:19 -05:00
kennethreitz 7c47796ac6 Update README.rst 2017-02-09 17:18:44 -05:00
kennethreitz 9c88519e63 only test 3.6 and 2.7 2017-02-09 17:15:22 -05:00
kennethreitz 50d4558ffa travis 2017-02-09 17:07:03 -05:00
kennethreitz 77bfce0bae rfc 3339, v0.1.7 2017-02-09 17:03:55 -05:00
kennethreitz 8aaa741793 v0.1.6 2017-01-24 12:46:15 -05:00
kennethreitz 5a442b3876 fix failing test 2017-01-01 17:36:42 -05:00
kennethreitz 4822487efe Merge pull request #46 from JoshuaRLi/update-authors
Update AUTHORS
2017-01-01 17:32:55 -05:00
Joshua Li e0ee61fd43 update AUTHORS 2017-01-01 16:42:18 -05:00
kennethreitz 08a654d523 v0.1.5 2016-12-30 18:59:32 -05:00
kennethreitz 0e260d761e Merge pull request #37 from moin18/decorator_remove
Type checks in comparison operators
2016-12-30 18:58:20 -05:00
Moin c9888a48e5 validate_class_type_arguments decorator 2016-12-29 16:23:53 +05:30
Moin 21743de790 test for AttributeError in MayaDT comparison operators 2016-12-29 14:42:59 +05:30
Moin 09c3e352e4 Merge branch 'master' of https://github.com/kennethreitz/maya into decorator_remove 2016-12-29 14:38:47 +05:30
Moin ba9e35525c modified maya_dt obj check decorator 2016-12-29 14:36:05 +05:30
kennethreitz 562403da0f Merge pull request #38 from moin18/slang_date
use local timezone to get the slang date
2016-12-28 15:07:07 -05:00
kennethreitz e96db15c0e Merge pull request #43 from timofurrer/python3
Support Python 3.3, 3.4, 3.5, 3.6
2016-12-28 15:06:11 -05:00
kennethreitz a3b86b6025 Merge pull request #44 from timofurrer/strproto
Implement str protocol for human readable datetime printing
2016-12-28 15:05:36 -05:00
Timo Furrer 2f47366cbf Implement str protocol for human readable datetime printing 2016-12-28 09:12:48 +01:00
Timo Furrer c17a358c66 Support Python 3.3, 3.4, 3.5, 3.6
ruamel.ordereddict is only needed for python 2.7 anyway.
So we should not depend on it in requirements.txt
2016-12-28 08:59:30 +01:00
kennethreitz b8300192c9 Merge pull request #39 from moin18/test_change
properties test at single place
2016-12-28 02:24:48 -05:00
kennethreitz d8f01a7789 Merge pull request #41 from JoshuaRLi/pip-win-fix
Fix file encoding issues preventing successful pip installation on Windows
2016-12-28 02:24:21 -05:00
kennethreitz 199a290b1d Merge pull request #42 from JoshuaRLi/test-dt-tz-fix
Fix erroneous test logic in test_dt_tz_translation, test_dt_tz_naive
2016-12-28 02:23:53 -05:00
Joshua Li 82d20ad1dc fix erroneous test logic with dt_tz_naive and dt_tz_translation 2016-12-27 22:32:39 -05:00
Joshua Li d6b8ac54ad README.rst is now read correctly with utf-8 encoding into the setup long_description, fixes python3 windows cmd installs via pip 2016-12-27 21:24:02 -05:00
Moin edfb9baae4 use local timezone to get the slang date 2016-12-27 04:56:40 +05:30
Moin 4fb95666ba properties test at single place 2016-12-27 04:51:43 +05:30
Moin 03243e2194 Type checks in comparison operators
Related to issue #33
2016-12-27 01:24:49 +05:30
kennethreitz 6420cc91d9 Merge pull request #30 from timofurrer/cleanup/fix-authors
Fix rst headings in AUTHORS file
2016-12-26 11:47:38 -05:00
kennethreitz 40eeea252d Merge pull request #31 from timofurrer/cleanup/remove-exec-flag
Remove executable flag from python files
2016-12-26 11:47:27 -05:00
kennethreitz 2452b30d96 Merge pull request #32 from timofurrer/cleanup/remove-substraction
Remove sub protocol
2016-12-26 11:47:08 -05:00
kennethreitz 4e009dc51a Merge pull request #34 from timofurrer/coverage
Add unit tests for weekday and week
2016-12-26 11:46:02 -05:00
kennethreitz d535739413 Merge pull request #35 from timofurrer/cleanup/tests
Make unit tests more valuable
2016-12-26 11:45:32 -05:00
Timo Furrer 299951bd0b Make unit tests more valuable 2016-12-26 12:01:54 +01:00
Timo Furrer 84555b1f5c Remove sub protocol 2016-12-26 11:17:46 +01:00
Timo Furrer 915337d2b4 Add unit tests for weekday and week 2016-12-26 11:10:02 +01:00
Timo Furrer e31f018a23 Remove executable flag from python files 2016-12-26 10:59:35 +01:00
Timo Furrer 0b64766b62 Fix rst headings in AUTHORS file 2016-12-26 10:56:13 +01:00
kennethreitz 5c255d2682 Merge pull request #29 from moin18/maya_operations
comparision operation support and subtraction of MayaDT object
2016-12-24 14:14:33 -05:00
kennethreitz 702eaab906 Merge pull request #28 from moin18/contributors
contributor firendly repository
2016-12-24 13:26:40 -05:00
Moin 5bbe383061 comparision operation support and subtraction of MayaDT object 2016-12-24 22:39:47 +05:30
Moin d40e698fb9 contributor firendly repository 2016-12-24 21:22:47 +05:30
kennethreitz 327f057e63 Merge pull request #27 from moin18/master
'week' and 'weekday' as properties to 'MayaDT' object
2016-12-24 00:45:38 -05:00
Moin 470516146a 'week' and 'weekday' as properties to 'MayaDT' object 2016-12-24 03:33:37 +05:30
kennethreitz dbed0555db _EPOCH_START 2016-12-23 13:11:25 -05:00
kennethreitz 2fce84195e v0.1.4 2016-12-21 13:24:53 -05:00
kennethreitz 7ab9e48d45 Merge pull request #25 from Factr/master
Added .gitignore
2016-12-20 22:19:15 -05:00
Adam Nelson ee1a8e2438 Added .gitignore
From https://github.com/github/gitignore/blob/master/Python.gitignore with Pycharm exclusion for .idea/
2016-12-20 16:08:29 -05:00
kennethreitz b0e91d6c0e Merge pull request #24 from Factr/master
Added tzlocal to setup.py
2016-12-20 14:30:11 -05:00
Adam Nelson bce5d13401 Merge branch 'master' of github.com:Factr/maya into HEAD 2016-12-20 13:36:19 -05:00
Adam Nelson b4a23d668d Added tzlocal as setup requirement 2016-12-20 13:34:49 -05:00
kennethreitz 90051da96d fix maya link to travis 2016-12-20 13:09:48 -05:00
kennethreitz 8f0ff0d68c skip 3 builds 2016-12-20 13:08:55 -05:00
kennethreitz fd1262a8e8 shields 2016-12-20 12:57:11 -05:00
kennethreitz 7558261dc8 basic travis file 2016-12-20 12:49:56 -05:00
kennethreitz 1407e688fd improve test name 2016-12-20 12:29:31 -05:00
kennethreitz 0c2b936111 cleanup tests 2016-12-20 12:27:16 -05:00
kennethreitz 9e72ef3d2f test for #19 2016-12-20 12:25:19 -05:00
kennethreitz eabba0b79e v0.1.3 2016-12-20 12:25:01 -05:00
Adam Nelson 0efc489ba1 Added tzlocal as a requirement as well 2016-12-19 17:15:35 -05:00
10 changed files with 496 additions and 57 deletions
+94
View File
@@ -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/
+9
View File
@@ -0,0 +1,9 @@
language: python
python:
- "2.7"
- "3.6"
# command to install dependencies
install: pip install pipenv; pipenv install --dev
# command to run tests
script: pipenv run pytest
+23
View File
@@ -0,0 +1,23 @@
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>`_)
- Joshua Li <joshua.r.li.98@gmail.com> (`@JoshuaRLi <https://github.com/JoshuaRLi>`_)
- Sébastien Eustace <sebastien@eustace.io> (`@sdispater <https://github.com/sdispater>`_)
+10
View File
@@ -0,0 +1,10 @@
[packages]
humanize = "*"
pytz = "*"
dateparser = "*"
"ruamel.yaml" = "*"
tzlocal = "*"
pendulum = ">=1.0"
[dev-packages]
pytest = "*"
Generated
+102
View File
@@ -0,0 +1,102 @@
{
"_meta": {
"sources": [
{
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
],
"requires": {},
"hash": {
"sha256": "5617ff73ba51e60721267b24dc01e83f33d2a3692870b60e394b0f75ed2dc313"
}
},
"default": {
"convertdate": {
"hash": "sha256:9c5d8dc984e51789ffaa92e988939ba8734c56ed718a3943998e7832fffa66ed",
"version": "==2.1.0"
},
"dateparser": {
"hash": "sha256:bbdb38e35dcf42653bbc88dc8870d0ef7eb5679af64b4f2ffc43d43acd3b24ba",
"version": "==0.5.1"
},
"ephem": {
"hash": "sha256:7a4c82b1def2893e02aec0394f108d24adb17bd7b0ca6f4bc78eb7120c0212ac",
"version": "==3.7.6.0"
},
"humanize": {
"hash": "sha256:a43f57115831ac7c70de098e6ac46ac13be00d69abbf60bdcac251344785bb19",
"version": "==0.5.1"
},
"jdatetime": {
"hash": "sha256:b6bb0bbd822eb0d3f9a55c4e8bfda0ccace3dcfa6d16bdcb29c124ad2ce66335",
"version": "==1.8.1"
},
"pendulum": {
"hash": "sha256:2417888ceddbb9c3903317ad321e27b2217aacf4ddcc1993ac3ad4db96f3a701",
"version": "==1.0.2"
},
"python-dateutil": {
"hash": "sha256:537bf2a8f8ce6f6862ad705cd68f9e405c0b5db014aa40fa29eab4335d4b1716",
"version": "==2.6.0"
},
"pytz": {
"hash": "sha256:a1ea35e87a63c7825846d5b5c81d23d668e8a102d3b1b465ce95afe1b3a2e065",
"version": "==2016.10"
},
"pytzdata": {
"hash": "sha256:cf28a9bbb4e7f94ae21f4a3c64439aa44f81d5814fe9989e9ab7374658b6e596",
"version": "==2016.10"
},
"regex": {
"hash": "sha256:45b62acff46cb886246e40227a872089d8d4972dbf2f114ec1ae64e5893e87bf",
"version": "==2017.02.08"
},
"ruamel.yaml": {
"hash": "sha256:7cfd653648a1d4a635ce7ae254b4dc6ec7df931a5a653c79e627547be5dda71b",
"version": "==0.13.13"
},
"six": {
"hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1",
"version": "==1.10.0"
},
"tzlocal": {
"hash": "sha256:d160c2ce4f8b1831dabfe766bd844cf9012f766539cf84139c2faac5201882ce",
"version": "==1.3"
},
"umalqurra": {
"hash": "sha256:719f6a36f908ada1c29dae0d934dd0f1e1f6e3305784edbec23ad719397de678",
"version": "==0.2"
}
},
"develop": {
"appdirs": {
"hash": "sha256:85e58578db8f29538f3109c11250c2a5514a2fcdc9890d9b2fe777eb55517736",
"version": "==1.4.0"
},
"packaging": {
"hash": "sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388",
"version": "==16.8"
},
"py": {
"hash": "sha256:2d4bba2e25fff58140e6bdce1e485e89bb59776adbe01d490baa6b1f37a3dd6b",
"version": "==1.4.32"
},
"pyparsing": {
"hash": "sha256:67101d7acee692962f33dd30b5dce079ff532dd9aa99ff48d52a3dad51d2fe84",
"version": "==2.1.10"
},
"pytest": {
"hash": "sha256:da0ab50c7eec0683bc24f1c1137db1f4111752054ecdad63125e7ec71316b813",
"version": "==3.0.6"
},
"setuptools": {
"hash": "sha256:5f74aabe68c441b99dca68c22796d5cbf532cb38b0aeada17d1d3988809de6e6",
"version": "==34.1.1"
},
"six": {
"hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1",
"version": "==1.10.0"
}
}
}
+37 -7
View File
@@ -1,5 +1,15 @@
Maya: Datetime for Humans™
==========================
Maya: Timestamps 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-!-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
@@ -30,11 +40,17 @@ Behold, datetimes for humans!
>>> tomorrow.slang_time()
'23 hours from now'
# Also: MayaDT.from_iso8601(...)
>>> tomorrow.iso8601()
'2016-12-16T15:11:30.263350Z'
'2017-02-10T22:17:01.445418Z'
# Also: MayaDT.from_rfc2822(...)
>>> tomorrow.rfc2822()
'Fri, 16 Dec 2016 20:11:30 -0000'
'Fri, 10 Feb 2017 22:17:01 GMT'
# Also: MayaDT.from_rfc3339(...)
>>> tomorrow.rfc3339()
'2017-02-10T22:17:01.44Z'
>>> tomorrow.datetime()
datetime.datetime(2016, 12, 16, 15, 11, 30, 263350, tzinfo=<UTC>)
@@ -47,9 +63,11 @@ Behold, datetimes for humans!
>>> rand_day = maya.when('2011-02-07', timezone='US/Eastern')
<MayaDT epoch=1297036800.0>
# Note how this is the 6th, not the 7th.
>>> rand_day.day
6
7
>>> rand_day.add(days=10).day
17
# Always.
>>> rand_day.timezone
@@ -61,7 +79,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 +108,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
Executable → Regular
+83 -9
View File
@@ -16,11 +16,31 @@ from datetime import datetime as Datetime
import pytz
import humanize
import dateparser
import iso8601
import dateutil.parser
import pendulum
from tzlocal import get_localzone
EPOCH_START = (1970, 1, 1)
_EPOCH_START = (1970, 1, 1)
def validate_class_type_arguments(operator):
"""
Decorator to validate all the arguments to function
are of the type of calling class
"""
def inner(function):
def wrapper(self, *args, **kwargs):
for arg in args + tuple(kwargs.values()):
if not isinstance(arg, self.__class__):
raise TypeError('unorderable types: {}() {} {}()'.format(
type(self).__name__, operator, type(arg).__name__))
return function(self, *args, **kwargs)
return wrapper
return inner
class MayaDT(object):
"""The Maya Datetime object."""
@@ -32,10 +52,46 @@ class MayaDT(object):
def __repr__(self):
return '<MayaDT epoch={}>'.format(self._epoch)
def __str__(self):
return self.rfc2822()
def __format__(self, *args, **kwargs):
"""Return's the datetime's format"""
return format(self.datetime(), *args, **kwargs)
@validate_class_type_arguments('==')
def __eq__(self, maya_dt):
return self._epoch == maya_dt._epoch
@validate_class_type_arguments('!=')
def __ne__(self, maya_dt):
return self._epoch != maya_dt._epoch
@validate_class_type_arguments('<')
def __lt__(self, maya_dt):
return self._epoch < maya_dt._epoch
@validate_class_type_arguments('<=')
def __le__(self, maya_dt):
return self._epoch <= maya_dt._epoch
@validate_class_type_arguments('>')
def __gt__(self, maya_dt):
return self._epoch > maya_dt._epoch
@validate_class_type_arguments('>=')
def __ge__(self, maya_dt):
return self._epoch >= maya_dt._epoch
def add(self, **kwargs):
""""Returns a new MayaDT object with the given offsets."""
return self.from_datetime(pendulum.instance(self.datetime()).add(**kwargs))
def subtract(self, **kwargs):
""""Returns a new MayaDT object with the given offsets."""
return self.from_datetime(pendulum.instance(self.datetime()).subtract(**kwargs))
# Timezone Crap
# -------------
@@ -67,7 +123,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
@@ -81,14 +137,18 @@ class MayaDT(object):
@classmethod
def from_iso8601(klass, string):
"""Returns MayaDT instance from iso8601 string."""
dt = iso8601.parse_date(string)
return klass.from_datetime(dt)
return parse(string)
@staticmethod
def from_rfc2822(string):
"""Returns MayaDT instance from rfc2822 string."""
return parse(string)
@staticmethod
def from_rfc3339(string):
"""Returns MayaDT instance from rfc3339 string."""
return parse(string)
# Exporters
# ---------
@@ -125,6 +185,10 @@ class MayaDT(object):
"""Returns an RFC 2822 representation of the MayaDT."""
return email.utils.formatdate(self.epoch, usegmt=True)
def rfc3339(self):
"""Returns an RFC 3339 representation of the MayaDT."""
return self.datetime().strftime("%Y-%m-%dT%H:%M:%S.%f")[:-4]+"Z"
# Properties
# ----------
@@ -140,6 +204,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
@@ -165,7 +238,8 @@ class MayaDT(object):
def slang_date(self):
""""Returns human slang representation of date."""
return humanize.naturaldate(self.datetime())
dt = self.datetime(naive=True, to_timezone=self.local_timezone)
return humanize.naturaldate(dt)
def slang_time(self):
""""Returns human slang representation of time."""
@@ -203,11 +277,11 @@ def when(string, timezone='UTC'):
def parse(string, day_first=False):
""""Returns a MayaDT instance for the machine-produced moment specified.
Powered by dateutil. Accepts most known formats. Useful for working with data.
Powered by pendulum. Accepts most known formats. Useful for working with data.
Keyword Arguments:
string -- string to be parsed
day_first -- if true, the first value (e.g. 01/05/2016) is parsed as day (default: False)
"""
dt = dateutil.parser.parse(string, dayfirst=day_first)
dt = pendulum.parse(string, day_first=day_first)
return MayaDT.from_datetime(dt)
-16
View File
@@ -1,16 +0,0 @@
-e .
dateparser==0.5.0
humanize==0.5.1
iso8601==0.1.11
jdatetime==1.8.1
py==1.4.32
pytest==3.0.5
python-dateutil==2.6.0
pytz==2016.10
regex==2016.11.21
ruamel.ordereddict==0.4.9
ruamel.yaml==0.13.4
six==1.10.0
typing==3.5.2.2
tzlocal==1.3
umalqurra==0.2
+8 -7
View File
@@ -16,8 +16,9 @@ except ImportError:
here = os.path.abspath(dirname(__file__))
def read(*parts):
return codecs.open(os.path.join(here, *parts), 'r').read()
with codecs.open(os.path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = '\n' + f.read()
if sys.argv[-1] == "publish":
os.system("python setup.py sdist bdist_wheel upload")
@@ -27,16 +28,16 @@ required = [
'humanize',
'pytz',
'dateparser',
'iso8601',
'python-dateutil',
'ruamel.yaml'
'ruamel.yaml',
'tzlocal',
'pendulum'
]
setup(
name='maya',
version='0.1.2',
version='0.1.8',
description='Datetimes for Humans.',
long_description= '\n' + read('README.rst'),
long_description=long_description,
author='Kenneth Reitz',
author_email='me@kennethreitz.com',
url='https://github.com/kennethreitz/maya',
Executable → Regular
+130 -18
View File
@@ -1,26 +1,73 @@
import pytest
from datetime import datetime
import copy
import maya
def test_rfc2822():
r = maya.now().rfc2822()
r = maya.parse('February 21, 1994').rfc2822()
d = maya.MayaDT.from_rfc2822(r)
assert r == 'Mon, 21 Feb 1994 00:00:00 GMT'
assert r == d.rfc2822()
def test_iso8601():
r = maya.now().iso8601()
r = maya.parse('February 21, 1994').iso8601()
d = maya.MayaDT.from_iso8601(r)
assert r == '1994-02-21T00:00:00Z'
assert r == d.iso8601()
def test_parse_iso8601():
string = '20161001T1430.4+05:30'
expected = '2016-10-01T09:00:00.400000Z'
d = maya.MayaDT.from_iso8601(string)
assert expected == d.iso8601()
string = '2016T14'
expected = '2016-01-01T14:00:00Z'
d = maya.MayaDT.from_iso8601(string)
assert expected == d.iso8601()
string = '2016-10T14'
expected = '2016-10-01T14:00:00Z'
d = maya.MayaDT.from_iso8601(string)
assert expected == d.iso8601()
string = '2012W05'
expected = '2012-01-30T00:00:00Z'
d = maya.MayaDT.from_iso8601(string)
assert expected == d.iso8601()
string = '2012W055'
expected = '2012-02-03T00:00:00Z'
d = maya.MayaDT.from_iso8601(string)
assert expected == d.iso8601()
string = '2012007'
expected = '2012-01-07T00:00:00Z'
d = maya.MayaDT.from_iso8601(string)
assert expected == d.iso8601()
string = '2016-W07T09'
expected = '2016-02-15T09:00:00Z'
d = maya.MayaDT.from_iso8601(string)
assert expected == d.iso8601()
def test_human_when():
r1 = maya.when('yesterday')
r2 = maya.when('today')
assert r2.day - r1.day == 1
assert (r2.day - r1.day) in (1, -30, -29, -28, -27)
def test_machine_parse():
r1 = maya.parse('August 14, 2015')
@@ -33,7 +80,7 @@ def test_machine_parse():
def test_dt_tz_translation():
d1 = maya.now().datetime()
d2 = maya.now().datetime(to_timezone='US/Eastern')
assert d1.hour - d2.hour == 5
assert (d1.hour - d2.hour) % 24 == 5
def test_dt_tz_naive():
@@ -42,18 +89,34 @@ def test_dt_tz_naive():
d2 = maya.now().datetime(to_timezone='US/Eastern', naive=True)
assert d2.tzinfo is None
assert d1.hour - d2.hour == 5
assert (d1.hour - d2.hour) % 24 == 5
def test_random_date():
d = maya.when('11-17-11 08:09:10')
assert d.year == 2011
assert d.month == 11
assert d.day == 17
assert d.hour == 8
assert d.minute == 9
assert d.second == 10
assert d.microsecond == 0
# Test properties for maya.when()
d1 = maya.when('11-17-11 08:09:10')
assert d1.year == 2011
assert d1.month == 11
assert d1.day == 17
assert d1.week == 46
assert d1.weekday == 4
assert d1.hour == 8
assert d1.minute == 9
assert d1.second == 10
assert d1.microsecond == 0
# Test properties for maya.parse()
d2 = maya.parse('February 29, 1992 13:12:34')
assert d2.year == 1992
assert d2.month == 2
assert d2.day == 29
assert d2.week == 9
assert d2.weekday == 6
assert d2.hour == 13
assert d2.minute == 12
assert d2.second == 34
assert d2.microsecond == 0
def test_print_date(capsys):
@@ -61,12 +124,14 @@ def test_print_date(capsys):
print(d)
out, err = capsys.readouterr()
assert out == '<MayaDT epoch=1321488000.0>\n'
assert out == 'Thu, 17 Nov 2011 00:00:00 GMT\n'
assert repr(d) == '<MayaDT epoch=1321488000.0>'
def test_invalid_date():
with pytest.raises(ValueError):
d = maya.when('another day')
maya.when('another day')
def test_slang_date():
@@ -79,7 +144,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 +154,51 @@ 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_rfc3339():
mdt = maya.when('2016-01-01')
out = mdt.rfc3339()
mdt2 = maya.MayaDT.from_rfc3339(out)
assert mdt.epoch == mdt2.epoch
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
# Check Exceptions
with pytest.raises(TypeError):
now == 1
with pytest.raises(TypeError):
now != 1
with pytest.raises(TypeError):
now < 1
with pytest.raises(TypeError):
now <= 1
with pytest.raises(TypeError):
now > 1
with pytest.raises(TypeError):
now >= 1