Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to make a time from "Today" or "Yesterday" and a time in Python?

Python has pretty good date parsing but is the only way to recognize a datetime such as "Today 3:20 PM" or "Yesterday 11:06 AM" by creating a new date today and doing subtractions?

like image 294
sh1mmer Avatar asked Feb 16 '09 02:02

sh1mmer


1 Answers

A library that I like a lot, and I'm seeing more and more people use, is python-dateutil but unfortunately neither it nor the other traditional big datetime parser, mxDateTime from Egenix can parse the word "tomorrow" in spite of both libraries having very strong "fuzzy" parsers.

The only library I've seen that can do this is magicdate. Examples:

>>> import magicdate
>>> magicdate.magicdate('today')
datetime.date(2009, 2, 15)
>>> magicdate.magicdate('tomorrow')
datetime.date(2009, 2, 16)
>>> magicdate.magicdate('yesterday')
datetime.date(2009, 2, 14)

Unfortunately this only returns datetime.date objects, and so won't include time parts and can't handle your example of "Today 3:20 PM".

So, you need mxDateTime for that. Examples:

>>> import mx.DateTime

>>> mx.DateTime.Parser.DateTimeFromString("Today 3:20 PM")
<mx.DateTime.DateTime object for '2009-02-15 15:20:00.00' at 28faa28>

>>> mx.DateTime.Parser.DateTimeFromString("Tomorrow 5:50 PM")
<mx.DateTime.DateTime object for '2009-02-15 17:50:00.00' at 2a86088>

EDIT: mxDateTime.Parser is only parsing the time in these examples and ignoring the words "today" and "tomorrow". So for this particular case you need to use a combo of magicdate to get the date and mxDateTime to get the time. My recommendation is to just use python-dateutils or mxDateTime and only accept the string formats they can parse.


EDIT 2: As noted in the comments it looks python-dateutil can now handle fuzzy parsing. I've also since discovered the parsedatetime module that was developed for use in Chandler and it works with the queries in this question:

>>> import parsedatetime.parsedatetime as pdt
>>> import parsedatetime.parsedatetime_consts as pdc
>>> c=pdc.Constants()
>>> p=pdt.Calendar(c)
>>> p.parse('Today 3:20 PM')
((2010, 3, 12, 15, 20, 0, 4, 71, -1), 3)
>>> p.parse('Yesterday 11:06 AM')
((2010, 3, 11, 11, 6, 0, 3, 70, -1), 3)

and for reference here is the current time:

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2010, 3, 12, 15, 23, 35, 951652)
like image 55
Van Gale Avatar answered Nov 15 '22 19:11

Van Gale