Compare commits

..

47 Commits

Author SHA1 Message Date
kennethreitz 0108ebe07e 0.3.4
Signed-off-by: Kenneth Reitz <me@kennethreitz.org>
2018-02-26 17:31:33 -05:00
kennethreitz a7d89be3c7 Merge pull request #118 from tbarron/mayadt_subtraction
Mayadt subtraction
2018-02-26 17:30:34 -05:00
kennethreitz 99ffb773bb Merge branch 'master' into mayadt_subtraction 2018-02-26 17:29:34 -05:00
kennethreitz b3293f898e Merge pull request #119 from tbarron/issue_104
Issue 104
2018-02-26 17:29:07 -05:00
kennethreitz 2d8015a13b Merge pull request #120 from radek-sprta/patch-1
Add date property to MayaDT
2018-02-26 17:28:08 -05:00
radek-sprta 9066ee862d Add date property to MayaDT 2018-02-03 12:37:25 +01:00
Tom Barron 5f362a8968 Adding myself to the AUTHORS file 2018-01-29 18:20:41 -05:00
Tom Barron 565fdd6a9e Add myself to AUTHORS file 2018-01-29 18:18:52 -05:00
Tom Barron 24063b5e1b New test and code to address issue 104 2018-01-29 18:10:36 -05:00
Tom Barron b57f4a6775 Proposed update to support MayaDT - MayaDT -> datetime.timedelta 2018-01-29 13:37:31 -05:00
kennethreitz 91e7f499e2 Merge pull request #111 from zed/patch-1
there is no os.dirname only os.path.dirname
2017-12-18 17:28:29 -05:00
kennethreitz be3a349b16 Merge pull request #113 from timofurrer/bugfix/open-encoding
Use codecs.open when relying on encoding
2017-12-18 17:28:20 -05:00
Timo Furrer f69a93b110 Use codecs.open when relying on encoding. Fixes #112 2017-12-18 18:59:58 +01:00
zed 86586e733c there is no os.dirname only os.path.dirname 2017-12-08 15:35:30 +03:00
kennethreitz cd7b5b4aae Merge pull request #109 from alysivji/add_pendulum_tz
Add timezone option for parse()
2017-12-03 13:47:31 -06:00
kennethreitz b70884a1ec Merge pull request #110 from zolrath/fix-prefer-past-test
Fix prefer_past test in December
2017-12-03 06:34:50 -06:00
Matt Furden 773cdecab5 Fix prefer_past test at end of year 2017-12-03 00:47:12 -08:00
Aly Sivji ca865cd840 Add timezone parameter to maya.parse() 2017-12-03 00:06:41 -06:00
kennethreitz 5cf40b2d2e Merge pull request #108 from timofurrer/feature/parse-year-first
Support year_first in maya.parse. Closes #102
2017-11-21 11:32:41 -05:00
Timo Furrer 93152fa7f4 Support year_first in maya.parse. Closes #102
This change adds support for a `year_first` keyword argument to the
`maya.parse` function. `maya` will forward this argument to pendulum
which then lets `dateutil.parse` do the work.
2017-11-21 13:19:55 +01:00
kennethreitz baa0660a9b Merge pull request #103 from zolrath/prefer-past
Add prefer_past option for when
2017-11-20 10:20:39 -05:00
Matt Furden fd62815ce5 Fix test variable name change 2017-10-21 09:42:23 -07:00
Matt Furden c0092e74ae Add prefer_past option for when
When parsing dates from websites when encountering ambiguous dates like "December 12th" this is interpreted in the future (when the current date is in October).

When parsing dates that we know must be in the past this is not the correct behavior.

Add a `prefer_past` keyword argument to `when` to allow the user to ensure the date is parsed as being in the past.
2017-10-15 21:49:03 -07:00
kennethreitz 79d017fdcf Merge pull request #100 from amalmurali47/patch-1
Fix typos and correct spelling.
2017-09-21 10:15:42 -04:00
Amal Murali 7331d0d855 Fix typos and correct spelling. 2017-09-21 18:02:15 +05:30
kennethreitz 9c90c0534a Merge pull request #99 from Miserlou/master
Fixes #98 - add support for time struct with test and docs
2017-09-20 13:45:03 -04:00
Rich Jones b9c501b0e4 Fixes #98 - add support for time struct with test and docs 2017-09-20 19:32:37 +02:00
kennethreitz 3a71ff0174 Update README.rst 2017-09-05 13:01:06 -04:00
kennethreitz 43cc1d5946 Merge pull request #97 from dimaspivak/master
Fix MayaInterval.iso8601()
2017-09-02 15:14:51 -04:00
Dima Spivak aecb643beb Add Dima Spivak to AUTHORS.rst 2017-09-02 11:50:27 -07:00
Dima Spivak fa966900e1 Fix MayaInterval.iso8601() 2017-09-02 11:47:32 -07:00
kennethreitz 892e589ef2 Update README.rst 2017-08-31 03:13:35 -04:00
kennethreitz 0f795738c0 Update README.rst 2017-08-31 03:13:16 -04:00
kennethreitz b333489081 Merge pull request #96 from stsievert/patch-1
Add XKCD #1883 to README
2017-08-30 13:12:11 -04:00
Scott Sievert 17a450eb5d Add XKCD #1883 to README 2017-08-30 12:06:08 -05:00
kennethreitz 8cd2158567 Merge pull request #87 from endast/patch-1
Update README.rst
2017-08-26 15:32:11 -04:00
kennethreitz 883b1b9b92 Merge pull request #90 from ibigpapa/master
Fix for issue #89
2017-08-26 15:31:15 -04:00
kennethreitz 414df5f3f5 Merge pull request #93 from timofurrer/patch-1
Fix typo in README. Closes #92
2017-07-28 13:46:33 -04:00
Timo Furrer 1694ed7cf8 Fix typo in README. Closes #92 2017-07-28 10:00:06 +02:00
Troy Harrison cbe9f6bae7 Adds test for issue #89 2017-06-28 14:27:57 -05:00
Troy Harrison 8bdd5c65fa Fixes issue #89 2017-06-28 14:26:54 -05:00
Magnus Wahlberg 4d96d06d70 Update README.rst
The example for intervals is missing an "s"

>>> import maya
>>> maya.interval(start=maya.now(), end=maya.now().add(days=1), interval=60*60)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'maya' has no attribute 'interval'
>>> maya.intervals(start=maya.now(), end=maya.now().add(days=1), interval=60*60)
<generator object intervals at 0x106acc0a0>
2017-06-23 08:44:20 +02:00
kennethreitz bbdb9b8762 Merge pull request #79 from robcarrington/fix-setup
Fixed setup.py bug by turning encoding into a keyword argument. Encod…
2017-05-30 22:12:00 -04:00
Robert Carrington 28ecad81bd Fixed setup.py bug by turning encoding into a keyword argument. Encoding parameter was being passed in the position belonging to the buffering parameter 2017-05-30 21:03:35 -05:00
kennethreitz c56c552184 Merge pull request #78 from moin18/seconds_or_timedelta_private
"seconds_or_timedelta" as private
2017-05-30 10:51:31 -04:00
Moin d5e4853886 updated test to use private _seconds_or_timedelta 2017-05-30 20:03:20 +05:30
Moin 28b3a849a9 declare seconds_or_timedelta as private function 2017-05-30 19:58:33 +05:30
8 changed files with 416 additions and 61 deletions
+2
View File
@@ -22,3 +22,5 @@ In chronological order:
- Joshua Li <joshua.r.li.98@gmail.com> (`@JoshuaRLi <https://github.com/JoshuaRLi>`_)
- Sébastien Eustace <sebastien@eustace.io> (`@sdispater <https://github.com/sdispater>`_)
- Evan Mattiza <emattiza@gmail.com> (`@emattiza <https://github.com/emattiza>`_)
- Dima Spivak <dima@spivak.ch> (`@dimaspivak <https://github.com/dimaspivak>`_)
- Tom Barron <tusculum@gmail.com> (`@dtbarron <https://github.com/tbarron>`_)
Generated
+245 -22
View File
@@ -1,11 +1,26 @@
{
"_meta": {
"hash": {
"sha256": "5617ff73ba51e60721267b24dc01e83f33d2a3692870b60e394b0f75ed2dc313"
"sha256": "e7c76d32bf7d24c6e3637eb39049c1543ba59729fe50da193414bde84a120587"
},
"host-environment-markers": {
"implementation_name": "cpython",
"implementation_version": "3.6.1",
"os_name": "posix",
"platform_machine": "x86_64",
"platform_python_implementation": "CPython",
"platform_release": "17.3.0",
"platform_system": "Darwin",
"platform_version": "Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64",
"python_full_version": "3.6.1",
"python_version": "3.6",
"sys_platform": "darwin"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
@@ -13,60 +28,268 @@
},
"default": {
"dateparser": {
"hashes": [
"sha256:e2629d2f8361722c6047138ca085256c9f2cf5cc657fd66122aa0564afa4dc33",
"sha256:f8c24317120b06f71691d28076764ec084a132be2a250a78fdf54f6b427cac95"
],
"version": "==0.6.0"
},
"humanize": {
"hashes": [
"sha256:a43f57115831ac7c70de098e6ac46ac13be00d69abbf60bdcac251344785bb19"
],
"version": "==0.5.1"
},
"pendulum": {
"version": "==1.2.0"
"hashes": [
"sha256:9196f0aa4eec534aaf02b45c47dccc6f74a255ecdab6c772cb6bcea6b22790e4",
"sha256:a34690d8d4fc8eab34ea2dd9a99482dbbf0b1f059fe25effe204dd59bceda069",
"sha256:1577a44b1f4bbc942136bce654df24e31735e1ff6aaa37e0a6207abf13868be9",
"sha256:f68f0f13498c9350ffc712765c4e0bdc824a4afd767d1a71933ff7be380bf75e",
"sha256:76d6861664126fef4cbbdc6218ca09d81c4ed8da4c6df9637e0069f7d820f901",
"sha256:327c89477e6ea0e240cd9f94c241747a534ac6f3e71c9b2f3298485ffc8939b2",
"sha256:4f1675010fd934aea011642c33c0dd9bc6954d9be7032c7f9ccfea1ac8d752d7",
"sha256:e996c34fb101c9c6d88a839c19af74d7c067b92ed3371274efcf4d4b6dc160a6"
],
"version": "==1.4.0"
},
"python-dateutil": {
"version": "==2.6.0"
"hashes": [
"sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c",
"sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca"
],
"version": "==2.6.1"
},
"pytz": {
"version": "==2017.2"
"hashes": [
"sha256:80af0f3008046b9975242012a985f04c5df1f01eed4ec1633d56cc47a75a6a48",
"sha256:feb2365914948b8620347784b6b6da356f31c9d03560259070b2f30cff3d469d",
"sha256:59707844a9825589878236ff2f4e0dc9958511b7ffaae94dc615da07d4a68d33",
"sha256:d0ef5ef55ed3d37854320d4926b04a4cb42a2e88f71da9ddfdacfde8e364f027",
"sha256:c41c62827ce9cafacd6f2f7018e4f83a6f1986e87bfd000b8cfbd4ab5da95f1a",
"sha256:8cc90340159b5d7ced6f2ba77694d946fc975b09f1a51d93f3ce3bb399396f94",
"sha256:dd2e4ca6ce3785c8dd342d1853dd9052b19290d5bf66060846e5dc6b8d6667f7",
"sha256:699d18a2a56f19ee5698ab1123bbcc1d269d061996aeb1eda6d89248d3542b82",
"sha256:fae4cffc040921b8a2d60c6cf0b5d662c1190fe54d718271db4eb17d44a185b7"
],
"version": "==2017.3"
},
"pytzdata": {
"version": "==2017.2"
"hashes": [
"sha256:cd5b72400a7378b3b45eef5929cbe97ed44c3368685c35c477e316ebaa7e1809",
"sha256:e87376f2ee7cb89af5ddea5ed07ce3e98a55f891d07ae87d8c49e99f069423f2"
],
"version": "==2017.3.1"
},
"regex": {
"version": "==2017.04.29"
},
"ruamel.ordereddict": {
"version": "==0.4.9"
"hashes": [
"sha256:28a542117efd479cff110711c28f34cb40636f670d427dc42710b5183fbd92c4",
"sha256:93064faef899911a7378443fcfb1f2e93e19706a324162fc71dd996c85b24f37",
"sha256:9c4b23f8a68470522a0cdfbdcffbe2f61d7659b5d505cb7c1a729a6805345210",
"sha256:45fed2f98e5ca0fc420ff31cbd9eccbee41e4d607569fddaba0faea36ef6043d",
"sha256:079c656874ba6c2e3332df488d4eff33b94b4e260e3901dce1553cb4f1f36c73",
"sha256:c1ef8f72944bef49261daaa83c7d77439f54f8deefefc0e2cf7144ac8b20ac1f",
"sha256:26795107acb81bb07ef832832548834b03846eb046e5ba9a5917ee012c68c1e6",
"sha256:3e2609e0e366b21c3db3d41159d99e7bd37e02caaba24bba77ec5cc594c62c4e",
"sha256:801e054c1aa163545d29e186a1bea779437a19b49c4da9e11049624c2d2bfd31",
"sha256:51306abdaac9e712b208066d284ddc7e3a332c77ad6054ba8d305d607609a328",
"sha256:660990e223ef2f71cb78b4e106a9a023652a31fd305051a901b0f87171b69e24",
"sha256:47230e1af3479810b1ef2bf23768b5195588a03eea6248b678d6893c48f58082",
"sha256:5f15a27c24ed4ad2ed492abe80ddf27d35d63ef6c0d8878c915de6bf9f36c6f3",
"sha256:67025161b70b0625749b1b89200da59fecc2fda9d1e46f9ef588f9a4af9fc48f",
"sha256:139678fc013b75e486e580c39b4c52d085ed7362e400960f8be1711a414f16b5"
],
"version": "==2018.1.10"
},
"ruamel.yaml": {
"version": "==0.14.12"
"hashes": [
"sha256:14d161558e3bf89e87d77c218098be22fa9a0d6d0bea40250fce525b1d0cbee2",
"sha256:fcfc24a21594c071cc4588e84b7657a1f47ebcf6037c6c43fa15c4bbd3989ec2",
"sha256:02babffd019911841ba01b76e23dfec7c9e9b2725503fb2698c4982fa1a6e835",
"sha256:c0908896e34b617ead40552cab03c1769bdc43d1da02419160dc900c5dfddde2",
"sha256:01e30ecb1b1c0ebf9fce814dc20dace402571517277799291202b61b22096c24",
"sha256:b6c5d5f03ba78e3f27c7188a00c4e09b6a4507fe3154ba40a294e09cb30ee016",
"sha256:9225c83952d28f302cfc23c3d9a6f8231bfd581476d7aff1e3c7de49eecb4ee9",
"sha256:c41e04b526d0153c9246cfab87d7ddefdc9f165cb8886a8ec48ba7a2b73069f6",
"sha256:6d05c5a5baf829c70916c226ef3200650846a7227de226bca8a59efaf88bb973",
"sha256:e3bbfe0d294e08fdbb0cb05485435a2ceb4e168e98b5dc611f051c1864986b4b",
"sha256:68c8f2986bcb91b6db1aea8698941769840c7257e951a9377048f7eff35be773",
"sha256:072f6364a89972e8dc0afdce3335a709d5464dfeaa4f736d092a54574338b874",
"sha256:5504398fc755a2b14c9983b2101161a8591a4b30812590cc1c365e7fcc117dfa",
"sha256:e2d2715bf92156bec5fb42e92e95dac1c4d9904f8a3d4e2d0c438758fe9092d7",
"sha256:6d7929b24e329d662fa43b657fddfee5260e2d35d0a543065cd755d4e17a9b2f",
"sha256:f2d02a4af5a13b09d0b823cdd0317b54f3e0115e50b5ac4d9840c3a1b566817f",
"sha256:8dc74821e4bb6b21fb1ab35964e159391d99ee44981d07d57bf96e2395f3ef75"
],
"version": "==0.15.35"
},
"six": {
"version": "==1.10.0"
"hashes": [
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb",
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9"
],
"version": "==1.11.0"
},
"tzlocal": {
"version": "==1.4"
"hashes": [
"sha256:4ebeb848845ac898da6519b9b31879cf13b6626f7184c496037b818e238f2c4e"
],
"version": "==1.5.1"
}
},
"develop": {
"appdirs": {
"version": "==1.4.3"
"alabaster": {
"hashes": [
"sha256:2eef172f44e8d301d25aff8068fddd65f767a3f04b5f15b0f4922f113aa1c732",
"sha256:37cdcb9e9954ed60912ebc1ca12a9d12178c26637abdf124e3cde2341c257fe0"
],
"version": "==0.7.10"
},
"packaging": {
"version": "==16.8"
"attrs": {
"hashes": [
"sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450",
"sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9"
],
"version": "==17.4.0"
},
"babel": {
"hashes": [
"sha256:ad209a68d7162c4cff4b29cdebe3dec4cef75492df501b0049a9433c96ce6f80",
"sha256:8ce4cb6fdd4393edd323227cba3a077bceb2a6ce5201c902c65e730046f41f14"
],
"version": "==2.5.3"
},
"certifi": {
"hashes": [
"sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296",
"sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d"
],
"version": "==2018.1.18"
},
"chardet": {
"hashes": [
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691",
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"
],
"version": "==3.0.4"
},
"docutils": {
"hashes": [
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6",
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274"
],
"version": "==0.14"
},
"idna": {
"hashes": [
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4",
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f"
],
"version": "==2.6"
},
"imagesize": {
"hashes": [
"sha256:6ebdc9e0ad188f9d1b2cdd9bc59cbe42bf931875e829e7a595e6b3abdc05cdfb",
"sha256:0ab2c62b87987e3252f89d30b7cedbec12a01af9274af9ffa48108f2c13c6062"
],
"version": "==0.7.1"
},
"jinja2": {
"hashes": [
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
],
"version": "==2.10"
},
"markupsafe": {
"hashes": [
"sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
],
"version": "==1.0"
},
"pluggy": {
"hashes": [
"sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff"
],
"version": "==0.6.0"
},
"py": {
"version": "==1.4.33"
"hashes": [
"sha256:8cca5c229d225f8c1e3085be4fcf306090b00850fefad892f9d96c7b6e2f310f",
"sha256:ca18943e28235417756316bfada6cd96b23ce60dd532642690dcfdaba988a76d"
],
"version": "==1.5.2"
},
"pyparsing": {
"pygments": {
"hashes": [
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
],
"version": "==2.2.0"
},
"pytest": {
"version": "==3.0.7"
"hashes": [
"sha256:b84878865558194630c6147f44bdaef27222a9f153bbd4a08908b16bf285e0b1",
"sha256:53548280ede7818f4dc2ad96608b9f08ae2cc2ca3874f2ceb6f97e3583f25bc4"
],
"version": "==3.3.2"
},
"setuptools": {
"version": "==35.0.2"
"pytz": {
"hashes": [
"sha256:80af0f3008046b9975242012a985f04c5df1f01eed4ec1633d56cc47a75a6a48",
"sha256:feb2365914948b8620347784b6b6da356f31c9d03560259070b2f30cff3d469d",
"sha256:59707844a9825589878236ff2f4e0dc9958511b7ffaae94dc615da07d4a68d33",
"sha256:d0ef5ef55ed3d37854320d4926b04a4cb42a2e88f71da9ddfdacfde8e364f027",
"sha256:c41c62827ce9cafacd6f2f7018e4f83a6f1986e87bfd000b8cfbd4ab5da95f1a",
"sha256:8cc90340159b5d7ced6f2ba77694d946fc975b09f1a51d93f3ce3bb399396f94",
"sha256:dd2e4ca6ce3785c8dd342d1853dd9052b19290d5bf66060846e5dc6b8d6667f7",
"sha256:699d18a2a56f19ee5698ab1123bbcc1d269d061996aeb1eda6d89248d3542b82",
"sha256:fae4cffc040921b8a2d60c6cf0b5d662c1190fe54d718271db4eb17d44a185b7"
],
"version": "==2017.3"
},
"requests": {
"hashes": [
"sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
"sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
],
"version": "==2.18.4"
},
"six": {
"version": "==1.10.0"
"hashes": [
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb",
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9"
],
"version": "==1.11.0"
},
"snowballstemmer": {
"hashes": [
"sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89",
"sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128"
],
"version": "==1.2.1"
},
"sphinx": {
"hashes": [
"sha256:b8baed19394af85b21755c68c7ec4eac57e8a482ed89cd01cd5d5ff72200fe0f",
"sha256:c39a6fa41bd3ec6fc10064329a664ed3a3ca2e27640a823dc520c682e4433cdb"
],
"version": "==1.6.6"
},
"sphinxcontrib-websupport": {
"hashes": [
"sha256:f4932e95869599b89bf4f80fc3989132d83c9faa5bf633e7b5e0c25dffb75da2",
"sha256:7a85961326aa3a400cd4ad3c816d70ed6f7c740acd7ce5d78cd0a67825072eb9"
],
"version": "==1.0.1"
},
"urllib3": {
"hashes": [
"sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
"sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
],
"version": "==1.22"
}
}
}
+17 -7
View File
@@ -10,7 +10,6 @@ Maya: Datetimes for Humans™
.. image:: https://img.shields.io/badge/SayThanks-!-1EAEDB.svg
:target: https://saythanks.io/to/kennethreitz
test
Datetimes are very frustrating to work with in Python, especially when dealing
with different locales on different systems. This library exists to make the
@@ -21,6 +20,8 @@ Datetimes should be interacted with via an API written for humans.
Maya is mostly built around the headaches and use-cases around parsing datetime data from websites.
.. image:: https://farm4.staticflickr.com/3702/33288285996_5b69d2b8f7_k_d.jpg
☤ Basic Usage of Maya
---------------------
@@ -64,6 +65,15 @@ Behold, datetimes for humans!
>>> rand_day = maya.when('2011-02-07', timezone='US/Eastern')
<MayaDT epoch=1297036800.0>
# Maya speaks Python.
>>> m = maya.MayaDT.from_datetime(datetime.utcnow())
>>> print(m)
Wed, 20 Sep 2017 17:24:32 GMT
>>> m = maya.MayaDT.from_struct(time.gmtime())
>>> print(m)
Wed, 20 Sep 2017 17:24:32 GMT
>>> rand_day.day
7
@@ -75,13 +85,13 @@ Behold, datetimes for humans!
UTC
# Range of hours in a day:
>>> maya.interval(start=maya.now(), end=maya.now().add(days=1), interval=60*60)
>>> maya.intervals(start=maya.now(), end=maya.now().add(days=1), interval=60*60)
<generator object intervals at 0x105ba5820>
☤ Advanced Usage of Maya
------------------------
In addition to timestamps, Maya also includes a wonderfuly powerful ``MayaInterval`` class, which represents a range of time (e.g. an event). With this class, you can perform a multitude of advanced calendar calculations with finese and ease.
In addition to timestamps, Maya also includes a wonderfuly powerful ``MayaInterval`` class, which represents a range of time (e.g. an event). With this class, you can perform a multitude of advanced calendar calculations with finesse and ease.
For example:
@@ -95,7 +105,7 @@ For example:
>>> event = MayaInterval(start=event_start, end=event_end)
From here, there a a number of methods available to you, which you can use to compare this event to another event.
From here, there are a number of methods available to you, which you can use to compare this event to another event.
@@ -114,7 +124,7 @@ From here, there a a number of methods available to you, which you can use to co
☤ What about Delorean, Arrow, & Pendulum?
-----------------------------------------
All these project complement eachother, and are friends. Pendulum, for example, helps power Maya's parsing.
All these project complement each other, and are friends. Pendulum, for example, helps power Maya's parsing.
Arrow, for example, is a fantastic library, but isn't what I wanted in a datetime library. In many ways, it's better than Maya for certain things. In some ways, in my opinion, it's not.
@@ -126,9 +136,9 @@ I think these projects complement each-other, personally. Maya is great for pars
☤ Installing Maya
-----------------
Installation is easy, with pip::
Installation is easy, with `pipenv <http://pipenv.org/>`_::
$ pip install maya
$ pipenv install maya
✨🍰✨
+1 -1
View File
@@ -1 +1 @@
__version__ = '0.3.2'
__version__ = '0.3.4'
+63 -19
View File
@@ -114,23 +114,30 @@ class MayaDT(object):
return hash(int(self.epoch))
def __add__(self, duration):
return self.add(seconds=seconds_or_timedelta(duration).total_seconds())
return self.add(seconds=_seconds_or_timedelta(duration).total_seconds())
def __radd__(self, duration):
return self + duration
def __sub__(self, duration):
return self.subtract(
seconds=seconds_or_timedelta(duration).total_seconds())
def __sub__(self, duration_or_date):
if isinstance(duration_or_date, MayaDT):
return self.subtract_date(dt=duration_or_date)
else:
return self.subtract(
seconds=_seconds_or_timedelta(duration_or_date).total_seconds())
def add(self, **kwargs):
""""Returns a new MayaDT object with the given offsets."""
"""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."""
"""Returns a new MayaDT object with the given offsets."""
return self.from_datetime(pendulum.instance(self.datetime()).subtract(**kwargs))
def subtract_date(self, **kwargs):
"""Returns a timedelta object with the duration between the dates"""
return timedelta(self.epoch - kwargs['dt'].epoch)
# Timezone Crap
# -------------
@@ -147,7 +154,9 @@ class MayaDT(object):
@property
def local_timezone(self):
"""Returns the name of the local timezone, for informational purposes."""
return self._local_tz.zone
if self._local_tz.zone in pytz.all_timezones:
return self._local_tz.zone
return self.timezone
@property
def _local_tz(self):
@@ -175,6 +184,14 @@ class MayaDT(object):
"""Returns MayaDT instance from datetime."""
return klass(klass.__dt_to_epoch(dt))
@classmethod
@validate_arguments_type_of_function(time.struct_time)
def from_struct(klass, struct, timezone=pytz.UTC):
"""Returns MayaDT instance from a 9-tuple struct (assumed to be from gmtime())"""
struct_time = time.mktime(struct) - utc_offset()
dt = Datetime.fromtimestamp(struct_time, timezone)
return klass(klass.__dt_to_epoch(dt))
@classmethod
def from_iso8601(klass, iso8601_string):
"""Returns MayaDT instance from iso8601 string."""
@@ -244,6 +261,10 @@ class MayaDT(object):
@property
def day(self):
return self.datetime().day
@property
def date(self):
return self.datetime().date()
@property
def week(self):
@@ -288,6 +309,16 @@ class MayaDT(object):
return humanize.naturaltime(dt)
def utc_offset():
"""Returns the current local time offset from UTC accounting for DST """
ts = time.localtime()
if ts[-1]:
offset = time.altzone
else:
offset = time.timezone
return offset
def to_utc_offset_naive(dt):
if dt.tzinfo is None:
return dt
@@ -331,7 +362,7 @@ class MayaInterval(object):
# Convert duration to timedelta if seconds were provided.
if duration:
duration = seconds_or_timedelta(duration)
duration = _seconds_or_timedelta(duration)
if not start:
start = end - duration
@@ -350,7 +381,7 @@ class MayaInterval(object):
def iso8601(self):
"""Returns an ISO 8601 representation of the MayaInterval."""
return '{0}/{1}'.format(self.start.iso6801, self.end.iso8601)
return '{0}/{1}'.format(self.start.iso8601(), self.end.iso8601())
@classmethod
def from_iso8601(cls, s):
@@ -448,7 +479,7 @@ class MayaInterval(object):
def split(self, duration, include_remainder=True):
# Convert seconds to timedelta, if appropriate.
duration = seconds_or_timedelta(duration)
duration = _seconds_or_timedelta(duration)
if duration <= timedelta(seconds=0):
raise ValueError('cannot call split with a non-positive timedelta')
@@ -465,7 +496,7 @@ class MayaInterval(object):
"""Returns a quanitzed interval."""
# Convert seconds to timedelta, if appropriate.
duration = seconds_or_timedelta(duration)
duration = _seconds_or_timedelta(duration)
timezone = pytz.timezone(timezone)
@@ -568,7 +599,7 @@ def now():
return MayaDT(epoch=epoch)
def when(string, timezone='UTC'):
def when(string, timezone='UTC', prefer_past=False):
""""Returns a MayaDT instance for the human moment specified.
Powered by dateparser. Useful for scraping websites.
@@ -579,10 +610,15 @@ def when(string, timezone='UTC'):
Keyword Arguments:
string -- string to be parsed
timezone -- timezone referenced from (default: 'UTC')
prefer_past -- prefer parsing ambiguous date as in the past
"""
dt = dateparser.parse(string,
settings={'TIMEZONE': timezone, 'RETURN_AS_TIMEZONE_AWARE': True, 'TO_TIMEZONE': 'UTC'})
settings = {'TIMEZONE': timezone, 'RETURN_AS_TIMEZONE_AWARE': True, 'TO_TIMEZONE': 'UTC'}
if prefer_past:
settings['PREFER_DATES_FROM'] = 'past'
dt = dateparser.parse(string, settings=settings)
if dt is None:
raise ValueError('invalid datetime input specified.')
@@ -590,20 +626,28 @@ def when(string, timezone='UTC'):
return MayaDT.from_datetime(dt)
def parse(string, day_first=False):
def parse(string, timezone='UTC', day_first=False, year_first=True):
""""Returns a MayaDT instance for the machine-produced moment specified.
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)
timezone -- timezone referenced from (default: 'UTC')
day_first -- if true, the first value (e.g. 01/05/2016) is parsed as day.
if year_first is set to True, this distinguishes between YDM and YMD. (default: False)
year_first -- if true, the first value (e.g. 2016/05/01) is parsed as year (default: True)
"""
dt = pendulum.parse(string, day_first=day_first)
options = {}
options['tz'] = timezone
options['day_first'] = day_first
options['year_first'] = year_first
dt = pendulum.parse(string, **options)
return MayaDT.from_datetime(dt)
def seconds_or_timedelta(duration):
def _seconds_or_timedelta(duration):
"""Returns `datetime.timedelta` object for the passed duration.
Keyword Arguments:
@@ -622,7 +666,7 @@ def seconds_or_timedelta(duration):
def intervals(start, end, interval):
"""Yields MayaDT objects between the start and end MayaDTs given, at a given interval (seconds or timedelta)."""
interval = seconds_or_timedelta(interval)
interval = _seconds_or_timedelta(interval)
current_timestamp = start
while current_timestamp.epoch < end.epoch:
+2 -8
View File
@@ -7,14 +7,8 @@ import codecs
from setuptools import setup
try:
# Python 3
from os import dirname
except ImportError:
# Python 2
from os.path import dirname
here = os.path.abspath(dirname(__file__))
here = os.path.abspath(os.path.dirname(__file__))
with codecs.open(os.path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = '\n' + f.read()
@@ -39,7 +33,7 @@ packages = [
# About dict to store version and package info
about = dict()
with open(os.path.join(here, 'maya', '__version__.py'), 'r', 'utf-8') as f:
with codecs.open(os.path.join(here, 'maya', '__version__.py'), 'r', encoding='utf-8') as f:
exec(f.read(), about)
setup(
+80 -4
View File
@@ -1,8 +1,11 @@
import pytest
import pytz
import copy
from datetime import timedelta
import time
from datetime import date, timedelta, datetime as Datetime
import maya
from maya.core import _seconds_or_timedelta # import private function
def test_rfc2822():
@@ -63,6 +66,31 @@ def test_parse_iso8601():
assert expected == d.iso8601()
def test_struct():
now = round(time.time())
ts = time.gmtime(now)
m = maya.MayaDT.from_struct(ts)
dt = Datetime.fromtimestamp(now, pytz.UTC)
assert m._epoch != None
assert m.datetime() == dt
ts = time.localtime(now)
m = maya.MayaDT.from_struct(ts)
dt = Datetime.fromtimestamp(time.mktime(ts) - maya.core.utc_offset(), pytz.UTC)
assert m._epoch != None
assert m.datetime() == dt
def test_issue_104():
e = 1507756331
t = Datetime.utcfromtimestamp(e)
t = maya.MayaDT.from_datetime(t)
assert str(t) == 'Wed, 11 Oct 2017 21:12:11 GMT'
t = time.gmtime(e)
t = maya.MayaDT.from_struct(t)
assert str(t) == 'Wed, 11 Oct 2017 21:12:11 GMT'
def test_human_when():
r1 = maya.when('yesterday')
r2 = maya.when('today')
@@ -155,11 +183,39 @@ def test_parse():
d = maya.parse('01/05/2016', day_first=True)
assert format(d) == '2016-05-01 00:00:00+00:00'
d = maya.parse('2016/05/01', year_first=True, day_first=False)
assert format(d) == '2016-05-01 00:00:00+00:00'
d = maya.parse('2016/01/05', year_first=True, day_first=True)
assert format(d) == '2016-05-01 00:00:00+00:00'
d = maya.parse('01/05/2016', timezone='UTC')
assert format(d) == '2016-01-05 00:00:00+00:00'
d = maya.parse('01/05/2016', timezone='US/Central')
assert format(d) == '2016-01-05 06:00:00+00:00'
def test_when_past():
next_month = str(maya.now().add(months=1).month)
this_year = maya.now().year
last_year = this_year - 1
future_date = maya.when(next_month)
past_date = maya.when(next_month, prefer_past=True)
assert future_date.year == this_year
if next_month == '1':
assert past_date.year == this_year
else:
assert past_date.year == last_year
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()
@@ -207,12 +263,12 @@ def test_comparison_operations():
def test_seconds_or_timedelta():
# test for value in seconds
assert maya.seconds_or_timedelta(1234) == timedelta(0, 1234)
assert _seconds_or_timedelta(1234) == timedelta(0, 1234)
# test for value as `datetime.timedelta`
assert maya.seconds_or_timedelta(timedelta(0, 1234)) == timedelta(0, 1234)
assert _seconds_or_timedelta(timedelta(0, 1234)) == timedelta(0, 1234)
# test for invalid value
with pytest.raises(TypeError):
maya.seconds_or_timedelta('invalid interval')
_seconds_or_timedelta('invalid interval')
def test_intervals():
@@ -238,3 +294,23 @@ def test_dunder_sub():
now = maya.now()
assert now - 1 == now.subtract(seconds=1)
assert now - timedelta(seconds=1) == now.subtract(seconds=1)
def test_mayaDT_sub():
now = maya.now()
then = now.add(days=1)
assert then - now == timedelta(24*60*60)
assert now - then == timedelta(-24*60*60)
def test_core_local_timezone(monkeypatch):
@property
def mock_local_tz(self):
class StaticTzInfo(object):
zone = 'local'
def __repr__(self):
return "<StaticTzInfo 'local'>"
return StaticTzInfo()
monkeypatch.setattr(maya.MayaDT, '_local_tz', mock_local_tz)
mdt = maya.MayaDT(0)
assert mdt.local_timezone == 'UTC'
+6
View File
@@ -582,3 +582,9 @@ def test_interval_from_datetime():
)
assert interval3.start == start
assert interval3.end == end
def test_interval_iso8601():
start = maya.when('11-17-11 08:09:10')
interval = maya.MayaInterval(start=start, duration=1)
assert interval.iso8601() == '2011-11-17T08:09:10Z/2011-11-17T08:09:11Z'