{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Periods" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Decimal fractions\n", "\n", "From: https://github.com/metomi/isodatetime/issues/147\n", "\n", ">The smallest value used may also have a decimal fraction, as in \"P0.5Y\" to indicate half a year. This decimal fraction may be specified with either a comma or a full stop, as in \"P0,5Y\" or \"P0.5Y\".\n", "\n", "https://en.wikipedia.org/wiki/ISO_8601" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(365.0, 0.0)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import metomi.isodatetime.parsers as parse\n", "\n", "d = parse.DurationParser().parse('P1Y')\n", "d.get_days_and_seconds()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "ename": "ISO8601SyntaxError", "evalue": "Invalid ISO 8601 duration representation: P0.5Y", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mISO8601SyntaxError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/metomi/isodatetime/parsers.py\u001b[0m in \u001b[0;36mparse\u001b[0;34m(self, expression)\u001b[0m\n\u001b[1;32m 618\u001b[0m \u001b[0mallow_truncated\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 619\u001b[0;31m \u001b[0massumed_time_zone\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 620\u001b[0m )\n", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/metomi/isodatetime/parsers.py\u001b[0m in \u001b[0;36mparse_timepoint_expression\u001b[0;34m(timepoint_expression, validate, **kwargs)\u001b[0m\n\u001b[1;32m 643\u001b[0m \u001b[0mparser\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mTimePointParser\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 644\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mparser\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimepoint_expression\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalidate\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mvalidate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/metomi/isodatetime/parsers.py\u001b[0m in \u001b[0;36mparse\u001b[0;34m(self, timepoint_string, dump_format, dump_as_parsed, validate)\u001b[0m\n\u001b[1;32m 259\u001b[0m \"\"\"\n\u001b[0;32m--> 260\u001b[0;31m \u001b[0mdate_info\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime_info\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparsed_expr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_info\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimepoint_string\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 261\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mdump_as_parsed\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/metomi/isodatetime/parsers.py\u001b[0m in \u001b[0;36mget_info\u001b[0;34m(self, timepoint_string)\u001b[0m\n\u001b[1;32m 466\u001b[0m \u001b[0mdate\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdate_time_time_zone\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 467\u001b[0;31m \u001b[0mkeys\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdate_info\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_date_info\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 468\u001b[0m \u001b[0mformat_key\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtype_key\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdate_expr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mkeys\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/metomi/isodatetime/parsers.py\u001b[0m in \u001b[0;36mget_date_info\u001b[0;34m(self, date_string, bad_types)\u001b[0m\n\u001b[1;32m 426\u001b[0m result.groupdict())\n\u001b[0;32m--> 427\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mISO8601SyntaxError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"date\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdate_string\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 428\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mISO8601SyntaxError\u001b[0m: Invalid ISO 8601 date representation: 0.5Y", "\nDuring handling of the above exception, another exception occurred:\n", "\u001b[0;31mISO8601SyntaxError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDurationParser\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'P0.5Y'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_days_and_seconds\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/metomi/isodatetime/parsers.py\u001b[0m in \u001b[0;36mparse\u001b[0;34m(self, expression)\u001b[0m\n\u001b[1;32m 620\u001b[0m )\n\u001b[1;32m 621\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mISO8601SyntaxError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 622\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mISO8601SyntaxError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"duration\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexpression\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 623\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtimepoint\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_is_week_date\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 624\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mISO8601SyntaxError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"duration\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexpression\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mISO8601SyntaxError\u001b[0m: Invalid ISO 8601 duration representation: P0.5Y" ] } ], "source": [ "d = parse.DurationParser().parse('P0.5Y')\n", "d.get_days_and_seconds()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Other libraries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### iso8601" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "ename": "ParseError", "evalue": "Unable to parse date string 'P1Y'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mParseError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0miso8601\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;31m# iso8601 does not seem to support periods\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0miso8601\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse_date\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"P1Y\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/iso8601/iso8601.py\u001b[0m in \u001b[0;36mparse_date\u001b[0;34m(datestring, default_timezone)\u001b[0m\n\u001b[1;32m 193\u001b[0m \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mISO8601_REGEX\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdatestring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mm\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 195\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mParseError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Unable to parse date string %r\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mdatestring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 196\u001b[0m \u001b[0mgroups\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroupdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mParseError\u001b[0m: Unable to parse date string 'P1Y'" ] } ], "source": [ "import iso8601\n", "# iso8601 does not seem to support periods\n", "iso8601.parse_date(\"P1Y\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Pendulum" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Duration(years=1, days=0)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pendulum\n", "pendulum.parse(\"P1Y\")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "ename": "ParserError", "evalue": "Unable to parse string [P0.5Y]", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mParserError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpendulum\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"P0.5Y\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/pendulum/parser.py\u001b[0m in \u001b[0;36mparse\u001b[0;34m(text, **options)\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0moptions\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"now\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"now\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpendulum\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_test_now\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_parse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0moptions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 21\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/pendulum/parser.py\u001b[0m in \u001b[0;36m_parse\u001b[0;34m(text, **options)\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mpendulum\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 36\u001b[0;31m \u001b[0mparsed\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbase_parse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0moptions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 37\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparsed\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdatetime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatetime\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/pendulum/parsing/__init__.py\u001b[0m in \u001b[0;36mparse\u001b[0;34m(text, **options)\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0m_options\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moptions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 70\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_normalize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_parse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0m_options\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0m_options\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 71\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 72\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/Development/python/workspace/notebooks/venv/lib/python3.7/site-packages/pendulum/parsing/__init__.py\u001b[0m in \u001b[0;36m_parse\u001b[0;34m(text, **options)\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;31m# If not strict\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0moptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"strict\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 124\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mParserError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Unable to parse string [{}]\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 125\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 126\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mParserError\u001b[0m: Unable to parse string [P0.5Y]" ] } ], "source": [ "pendulum.parse(\"P0.5Y\")" ] } ], "metadata": { "kernelspec": { "display_name": "kinow-notebooks", "language": "python", "name": "kinow-notebooks" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }