3

You can parse a string representing a time, in Python, by using the strptime method. There are numerous working examples on stackoverflow:

Converting string into datetime

However, what if your string represented a time range, as opposed to a specific time; how could you parse the string using the strptime method?

For example, let’s say you have a user input a start and finish time.

studyTime = input("Please enter your study period (start time – finish time)")

You could prompt, or even force, the user to enter the time in a specific format.

studyTime = input("Please enter your study period (hh:mm - hh:mm): ")

Let’s say the user enters 03:00 PM – 05:00 PM. How can we then parse this string using strptime?

formatTime = datetime.datetime.strptime(studyTime, "%I:%M %p")

The above formatTime would only work on a single time, i.e. 03:00 PM, not a start – finish time, 03:00 – 05:00. And the following would mean excess format data and a ValueError would be raised.

formatTime = datetime.datetime.strptime(studyTime, “%I:%M %p - %I:%M %p”)

Of course there are alternatives, such as having the start and finish times as separate strings. However, my question is specifically, is there a means to parse one single string, that contains more than one time representation, using something akin to the below.

formatTime = datetime.datetime.strptime(studyTime, “%I:%M %p - %I:%M %p”)
martineau
  • 119,623
  • 25
  • 170
  • 301
Andrew Hardiman
  • 929
  • 1
  • 15
  • 30

1 Answers1

2

strptime() can only parse a single datetime string representation.

You have to split the input string by - and load each item with strptime():

>>> from datetime import datetime
>>>
>>> s = "03:00 PM - 05:00 PM"
>>> [datetime.strptime(item, "%I:%M %p") for item in s.split(" - ")]
[datetime.datetime(1900, 1, 1, 15, 0), datetime.datetime(1900, 1, 1, 17, 0)]

Also checked the popular third-parties: dateutil, delorean and arrow - don't think they provide a datetime range parsing functionality. The dateutil's fuzzy_with_tokens() looked promising, but it is throwing errors:

>>> from dateutil.parser import parse
>>> s = "03:00 PM - 05:00 PM"
>>> parse(s, fuzzy_with_tokens=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/user/.virtualenvs/so/lib/python2.7/site-packages/dateutil/parser.py", line 1008, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/Users/user/.virtualenvs/so/lib/python2.7/site-packages/dateutil/parser.py", line 390, in parse
    res, skipped_tokens = self._parse(timestr, **kwargs)
TypeError: 'NoneType' object is not iterable

which probably means it is not supposed to parse multiple datetimes too.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks alecxe, I guessed this would be the case. However, as I am new to Python, and programming in general, I was curious to learn of any possible alternative ways this problem could be handled. I suppose I could always write my own function that provides a `datetime` *range* parsing functionality! – Andrew Hardiman Jan 17 '16 at 15:04
  • @mugman yeah. Definitely do that. Additionally you may check that the format is what you expect to see. For instance, you can apply a regular expression check with this pattern: `pattern = re.compile(r"\d{2}:\d{2} - \d{2}:\d{2}")` and then split the string by dash and load with `strptime` handling the exceptions. Just thoughts. – alecxe Jan 17 '16 at 15:07