appengine_form_utils /

Full commit


HumanDateTime: when you want to provide a field that lets your users input dates like "yesterday".

Uses parsedatetime to do this. Assumes that parsedatetime lives in a module called vendor.

Based off the patch at: <>, with mods to
get it working on appengine


import datetime
from google.appengine.ext.db import djangoforms

### HumanDateTimeField ###
from vendor.parsedatetime import parsedatetime

#The constructor compiles a bunch of regexs, might as well do it only once.
parse_calendar = parsedatetime.Calendar()

def parse_date_time(string):
    # parsedatetime seems to have a bug in it where MM-DD-YY(YY) dates are not accepted, and return the current date.
    # this might be proper for some usages (although I don't know what), but is not proper when you're
    # trying to feed a date into this picker
    # So, do a find and replace on and - and change them to /s.
    # This shouldn't cause other problems, but it is possible. WD-rpw 02-19-2011
    string = string.replace("-", "/")

    tup, flag = parse_calendar.parse(string)
    if (flag == 0):     # The string could not be parsed
        raise ValueError, "Unable to parse date/time."
    if (flag == 1):     # This was just a date
        value = datetime.datetime(*(tup[:3])) 
        value = datetime.datetime(*(tup[:6]))
    return value

class HumanDateTimeField(djangoforms.forms.Field):
    Uses the parsedatetime library to clean the value thereby allowing
    many different date-formats, including human readable strings like,
    "tomorrow" and "thursday at 10 pm".
    parsedatetime library:
    def clean(self, value):
        Validates that the input can be converted to a datetime. Returns a Python
        datetime.datetime object.
        super(HumanDateTimeField, self).clean(value)
        if value in (None, ''):
            return None
        if isinstance(value, datetime.datetime):
            return value
        if isinstance(value,
            return datetime.datetime(value.year, value.month,
            return parse_date_time(value)
        except ValueError:
        raise djangoforms.forms.ValidationError(
            u'Enter a valid date/time, like "today", "next tuesday at 2 am", "2006-10-28", or "10/24/99"')