{"info":{"author":"Víctor Muñoz","author_email":"victorm@marshland.es","bugtrack_url":null,"classifiers":["Development Status :: 4 - Beta","Intended Audience :: Developers","License :: OSI Approved :: ISC License (ISCL)","Operating System :: OS Independent","Programming Language :: Python :: 3","Topic :: Software Development :: Libraries :: Python Modules"],"description":"# isoduration: Operations with ISO 8601 durations.\n\n[![PyPI Package](https://img.shields.io/pypi/v/isoduration?style=flat-square)](https://pypi.org/project/isoduration/)\n\n## What is this.\n\nISO 8601 is most commonly known as a way to exchange datetimes in textual format. A\nlesser known aspect of the standard is the representation of durations. They have a\nshape similar to this:\n\n```\nP3Y6M4DT12H30M5S\n```\n\nThis string represents a duration of 3 years, 6 months, 4 days, 12 hours, 30 minutes,\nand 5 seconds.\n\nThe state of the art of ISO 8601 duration handling in Python is more or less limited to\nwhat's offered by [`isodate`](https://pypi.org/project/isodate/). What we are trying to\nachieve here is to address the shortcomings of `isodate` (as described in their own\n[_Limitations_](https://github.com/gweis/isodate/#limitations) section), and a few of\nour own annoyances with their interface, such as the lack of uniformity in their\nhandling of types, and the use of regular expressions for parsing.\n\n## How to use it.\n\nThis package revolves around the [`Duration`](src/isoduration/types.py) type.\n\nGiven a ISO duration string we can produce such a type by using the `parse_duration()`\nfunction:\n\n```py\n>>> from isoduration import parse_duration\n>>> duration = parse_duration(\"P3Y6M4DT12H30M5S\")\n>>> duration.date\nDateDuration(years=Decimal('3'), months=Decimal('6'), days=Decimal('4'), weeks=Decimal('0'))\n>>> duration.time\nTimeDuration(hours=Decimal('12'), minutes=Decimal('30'), seconds=Decimal('5'))\n```\n\nThe `date` and `time` portions of the parsed duration are just regular\n[dataclasses](https://docs.python.org/3/library/dataclasses.html), so their members can\nbe accessed in a non-surprising way.\n\nBesides just parsing them, a number of additional operations are available:\n\n- Durations can be compared and negated:\n  ```py\n  >>> parse_duration(\"P3Y4D\") == parse_duration(\"P3Y4DT0H\")\n  True\n  >>> -parse_duration(\"P3Y4D\")\n  Duration(DateDuration(years=Decimal('-3'), months=Decimal('0'), days=Decimal('-4'), weeks=Decimal('0')), TimeDuration(hours=Decimal('0'), minutes=Decimal('0'), seconds=Decimal('0')))\n  ```\n- Durations can be added to, or subtracted from, Python datetimes:\n  ```py\n  >>> from datetime import datetime\n  >>> datetime(2020, 3, 15) + parse_duration(\"P2Y\")\n  datetime.datetime(2022, 3, 15, 0, 0)\n  >>> datetime(2020, 3, 15) - parse_duration(\"P33Y1M4D\")\n  datetime.datetime(1987, 2, 11, 0, 0)\n  ```\n- Durations are hashable, so they can be used as dictionary keys or as part of sets.\n- Durations can be formatted back to a ISO 8601-compliant duration string:\n  ```py\n  >>> from isoduration import parse_duration, format_duration\n  >>> format_duration(parse_duration(\"P11YT2H\"))\n  'P11YT2H'\n  >>> str(parse_duration(\"P11YT2H\"))\n  'P11YT2H'\n  ```\n\n## How to improve it.\n\nThese steps, in this order, should land you in a development environment:\n\n```sh\ngit clone git@github.com:bolsote/isoduration.git\ncd isoduration/\npython -m venv ve\n. ve/bin/activate\npip install -U pip\npip install -e .\npip install -r requirements/dev.txt\n```\n\nAdapt to your own likings and/or needs.\n\nTesting is driven by [tox](https://tox.readthedocs.io). The output of `tox -l` and a\ncareful read of [tox.ini](tox.ini) should get you there.\n\n## FAQs.\n\n### How come `P1Y != P365D`?\nSome years have 366 days. If it's not always the same, then it's not the same.\n\n### Why do you create your own types, instead of somewhat shoehorning a `timedelta`?\n`timedelta` cannot represent certain durations, such as those involving years or months.\nSince it cannot represent all possible durations without dangerous arithmetic, then it\nmust not be the right type.\n\n### Why don't you use regular expressions to parse duration strings?\n[Regular expressions should only be used to parse regular languages.](https://stackoverflow.com/a/1732454)\n\n### Why is parsing the inverse of formatting, but the converse is not true?\nBecause this wonderful representation is not unique.\n\n### Why do you support `<insert here a weird case>`?\nProbably because the standard made me to.\n\n### Why do you not support `<insert here a weird case>`?\nProbably because the standard doesn't allow me to.\n\n### Why is it not possible to subtract a datetime from a duration?\nI'm confused.\n\n### Why should I use this over some other thing?\nYou shouldn't do what people on the Internet tell you to do.\n\n### Why are ISO standards so strange?\nYes.\n\n## References.\n\n- [XML Schema Part 2: Datatypes, Appendix D](https://www.w3.org/TR/xmlschema-2/#isoformats):\n  This excitingly named document contains more details about ISO 8601 than any human\n  should be allowed to understand.\n- [`isodate`](https://pypi.org/project/isodate/): The original implementation of ISO\n  durations in Python. Worth a look. But ours is cooler.\n\n\n","description_content_type":"text/markdown","docs_url":null,"download_url":"","downloads":{"last_day":-1,"last_month":-1,"last_week":-1},"dynamic":null,"home_page":"https://github.com/bolsote/isoduration","keywords":"datetime,date,time,duration,duration-parsing,duration-string,iso8601,iso8601-duration","license":"","license_expression":null,"license_files":null,"maintainer":"","maintainer_email":"","name":"isoduration","package_url":"https://pypi.org/project/isoduration/","platform":"","project_url":"https://pypi.org/project/isoduration/","project_urls":{"Bug Reports":"https://github.com/bolsote/isoduration/issues","Changelog":"https://github.com/bolsote/isoduration/blob/master/CHANGELOG","Homepage":"https://github.com/bolsote/isoduration","Repository":"https://github.com/bolsote/isoduration"},"provides_extra":null,"release_url":"https://pypi.org/project/isoduration/20.11.0/","requires_dist":["arrow (>=0.15.0)"],"requires_python":">=3.7","summary":"Operations with ISO 8601 durations","version":"20.11.0","yanked":false,"yanked_reason":null},"last_serial":8552874,"ownership":{"organization":null,"roles":[{"role":"Owner","user":"victorm"}]},"releases":{"20.11.0":[{"comment_text":"","core-metadata":{"sha256":"440045201154827793cad24bafbd54deca6800819259e3b17f6edbc06ca7b56b"},"digests":{"blake2b_256":"7b55e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a","md5":"c5f76c264bf80cca84b99c48d8af5afb","sha256":"b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"},"downloads":-1,"filename":"isoduration-20.11.0-py3-none-any.whl","has_sig":false,"md5_digest":"c5f76c264bf80cca84b99c48d8af5afb","packagetype":"bdist_wheel","python_version":"py3","requires_python":">=3.7","size":11321,"upload_time":"2020-11-01T10:59:58","upload_time_iso_8601":"2020-11-01T10:59:58.020369Z","url":"https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl","yanked":false,"yanked_reason":null},{"comment_text":"","core-metadata":false,"digests":{"blake2b_256":"7c1a3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead","md5":"865d2cb9d07342ea66c75cbf8a425cba","sha256":"ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"},"downloads":-1,"filename":"isoduration-20.11.0.tar.gz","has_sig":false,"md5_digest":"865d2cb9d07342ea66c75cbf8a425cba","packagetype":"sdist","python_version":"source","requires_python":">=3.7","size":11649,"upload_time":"2020-11-01T11:00:00","upload_time_iso_8601":"2020-11-01T11:00:00.312591Z","url":"https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz","yanked":false,"yanked_reason":null}]},"urls":[{"comment_text":"","core-metadata":{"sha256":"440045201154827793cad24bafbd54deca6800819259e3b17f6edbc06ca7b56b"},"digests":{"blake2b_256":"7b55e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a","md5":"c5f76c264bf80cca84b99c48d8af5afb","sha256":"b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"},"downloads":-1,"filename":"isoduration-20.11.0-py3-none-any.whl","has_sig":false,"md5_digest":"c5f76c264bf80cca84b99c48d8af5afb","packagetype":"bdist_wheel","python_version":"py3","requires_python":">=3.7","size":11321,"upload_time":"2020-11-01T10:59:58","upload_time_iso_8601":"2020-11-01T10:59:58.020369Z","url":"https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl","yanked":false,"yanked_reason":null},{"comment_text":"","core-metadata":false,"digests":{"blake2b_256":"7c1a3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead","md5":"865d2cb9d07342ea66c75cbf8a425cba","sha256":"ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"},"downloads":-1,"filename":"isoduration-20.11.0.tar.gz","has_sig":false,"md5_digest":"865d2cb9d07342ea66c75cbf8a425cba","packagetype":"sdist","python_version":"source","requires_python":">=3.7","size":11649,"upload_time":"2020-11-01T11:00:00","upload_time_iso_8601":"2020-11-01T11:00:00.312591Z","url":"https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz","yanked":false,"yanked_reason":null}],"vulnerabilities":[]}
