0

The following date patterns

1st January
30th April

are easily parsed into instances of datetime.date via dateutil.parser.parse():

In [1]:from dateutil.parser import parse

In [2]: parse('1st January')
Out[2]: datetime.datetime(2012, 1, 1, 0, 0)

In [3]: parse('8th April')
Out[3]: datetime.datetime(2012, 4, 30, 0, 0)

How can a future date be returned from parsing?

I.e. parsing '1st January' would return datetime.datetime(2013, 1, 1, 0, 0), 1st January 2013 and not 1st January 2012. Any elegant solution?

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
Joseph Victor Zammit
  • 14,760
  • 10
  • 76
  • 102

1 Answers1

4

Starting with mensi's excellent answer to your previous question, here's a solution that takes dates without a specified year and makes sure they're not in the past. If the year is given as part of the string it is kept intact.

import datetime
import dateutil

def parse(date_string):
    result = dateutil.parser.parse(date_string, default=datetime.datetime(1581, 1, 1))
    if result.year == 1581:
        now = datetime.datetime.now()
        result = result.replace(year=now.year)
        if result < now:
            result = result.replace(year=now.year + 1)
    return result

parse('8th April')
Community
  • 1
  • 1
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Thanks! However right now it doesn't work. `dateutil.parse` will not work so I'm importing `parse` via `from dateutil.parser import parse` and renaming your method `parse` to `parse_future`. Simple steps to get it running however once it runs it returns `datetime.datetime(1581, 4, 8, 0, 0)`. – Joseph Victor Zammit Apr 12 '12 at 19:19
  • I'm debugging. The `result.replace(year=now.year + 1)` is the piece that's not working. – Joseph Victor Zammit Apr 12 '12 at 19:28
  • Problem is, even "28th April" gets to 2013, whereas I want that to remain the same. Working on it, will edit your answer, and if you agree, please approve. Cheers! – Joseph Victor Zammit Apr 12 '12 at 19:35
  • @JosvicZammit, `replace` doesn't alter the datetime, it returns a new one - that's the big mistake I made originally. I don't know why my updated code wouldn't work for "28th April", did you copy it exactly? – Mark Ransom Apr 12 '12 at 19:50
  • Exactly I understood the `replace` issue but when going to fix it I noticed you had fixed it yourself. Yep I did copy exactly your code. Did you see my edit? Practically with 1581 a new date is always "newer"! Consequently the year is *always* replaced with `current_date+1`. Hence I changed `1581` with `today's date`. Cheers! – Joseph Victor Zammit Apr 12 '12 at 19:52
  • @JosvicZammit, your edit was lost - if you look at the history you'll see it isn't there. I never saw it. Since the 1581 is replaced immediately after it's detected I don't see how it would matter. Using today's date as a default fails when the string is "8th April 2012" because it modifies it to 2013. That might not be important to you if you never get a year as part of the date, but I want it to be part of a robust solution. – Mark Ransom Apr 12 '12 at 20:00
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/10019/discussion-between-josvic-zammit-and-mark-ransom) – Joseph Victor Zammit Apr 12 '12 at 20:06