gweis / isodate

ISO 8601 date/time parser
BSD 3-Clause "New" or "Revised" License
155 stars 59 forks source link

Missing support for time intervals #77

Open tobixen opened 2 years ago

tobixen commented 2 years ago

I'm working on my calendar-cli.

A calendar event typically spans a time interval, and ISO 8601 does specify three standard ways of writing a time interval (according to wikipedia. I've sort of invented my own way of writing time intervals, but I thought it would be a good idea to support the standard as well. Actually doing the parsing of ISO time intervals is however out of the scope of calendar-cli, and I was expecting someone else had already written the code for it. Using a popular search engine, I found the isodate library - but apparently, it does not support parsing time intervals.

Is it on the roadmap? Eventually, if I would do the work myself, would someone assist me with design review, code review and merging? (I can't give any commitments on time frame for this one, right now I have lots of available time by the computer, but it may be years until next time).

MyForest commented 1 year ago

Note that rdflib is using parse_datetime which trips up when passed a string such as this:

2023-10-01T22:15:00+00:00/2023-10-01T22:18:00+00:0

Here's a test case using rdflib in one case and then isodate:

FROM python

RUN python -m pip install rdflib

RUN echo '<> <http://purl.org/dc/terms/date> "2023-10-01T22:15:00+00:00/2023-10-01T22:18:00+00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .' > data.ttl

RUN cat data.ttl

RUN echo "Show rdflib using isodate..."

RUN python -c "from rdflib import Graph; g=Graph(); g.parse('data.ttl'); print(g.serialize())"

RUN echo "Now use isodate directly..."

RUN python -c "from isodate import parse_datetime; print(parse_datetime('2023-10-01T22:15:00+00:00/2023-10-01T22:18:00+00:00'))"
$ docker build .
STEP 1/8: FROM python
STEP 2/8: RUN python -m pip install rdflib
Collecting rdflib
  Downloading rdflib-7.0.0-py3-none-any.whl (531 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 531.9/531.9 kB 1.3 MB/s eta 0:00:00
Collecting isodate<0.7.0,>=0.6.0
  Downloading isodate-0.6.1-py2.py3-none-any.whl (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.7/41.7 kB 2.4 MB/s eta 0:00:00
Collecting pyparsing<4,>=2.1.0
  Downloading pyparsing-3.1.1-py3-none-any.whl (103 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.1/103.1 kB 2.7 MB/s eta 0:00:00
Collecting six
  Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, pyparsing, isodate, rdflib
Successfully installed isodate-0.6.1 pyparsing-3.1.1 rdflib-7.0.0 six-1.16.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip available: 22.3.1 -> 23.2.1
[notice] To update, run: pip install --upgrade pip
--> 80d4443ecc73
STEP 3/8: RUN echo '<> <http://purl.org/dc/terms/date> "2023-09-04T02:00:00+00:00/2023-09-04T02:30:00+00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .' > data.ttl
--> 8b4af12c7fe9
STEP 4/8: RUN cat data.ttl
<> <http://purl.org/dc/terms/date> "2023-09-04T02:00:00+00:00/2023-09-04T02:30:00+00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
--> 801a2c21a7c7
STEP 5/8: RUN echo "Show rdflib using isodate..."
Show rdflib using isodate...
--> e52c88d1667d
STEP 6/8: RUN python -c "from rdflib import Graph; g=Graph(); g.parse('data.ttl'); print(g.serialize())"
Failed to convert Literal lexical form to value. Datatype=http://www.w3.org/2001/XMLSchema#dateTime, Converter=<function parse_datetime at 0x7fd90b497420>
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/isodate/isodatetime.py", line 51, in parse_datetime
    datestring, timestring = datetimestring.split('T')
    ^^^^^^^^^^^^^^^^^^^^^^
ValueError: too many values to unpack (expected 2)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/rdflib/term.py", line 2119, in _castLexicalToPython
    return conv_func(lexical)  # type: ignore[arg-type]
           ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/isodate/isodatetime.py", line 53, in parse_datetime
    raise ISO8601Error("ISO 8601 time designator 'T' missing. Unable to"
isodate.isoerror.ISO8601Error: ISO 8601 time designator 'T' missing. Unable to parse datetime string '2023-09-04T02:00:00+00:00/2023-09-04T02:30:00+00:00'
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<file:///data.ttl> dcterms:date "2023-09-04T02:00:00+00:00/2023-09-04T02:30:00+00:00"^^xsd:dateTime .

--> 1fbdde804601
STEP 7/8: RUN echo "Now use isodate directly..."
Now use isodate directly...
--> 8f697d0e96de
STEP 8/8: RUN python -c "from isodate import parse_datetime; print(parse_datetime('2023-09-04T02:00:00+00:00/2023-09-04T02:30:00+00:00'))"
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/isodate/isodatetime.py", line 51, in parse_datetime
    datestring, timestring = datetimestring.split('T')
    ^^^^^^^^^^^^^^^^^^^^^^
ValueError: too many values to unpack (expected 2)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.11/site-packages/isodate/isodatetime.py", line 53, in parse_datetime
    raise ISO8601Error("ISO 8601 time designator 'T' missing. Unable to"
isodate.isoerror.ISO8601Error: ISO 8601 time designator 'T' missing. Unable to parse datetime string '2023-09-04T02:00:00+00:00/2023-09-04T02:30:00+00:00'
Error: building at STEP "RUN python -c "from isodate import parse_datetime; print(parse_datetime('2023-09-04T02:00:00+00:00/2023-09-04T02:30:00+00:00'))"": while running runtime: exit status 1