Re: worse date converter
Christopher Singley <[email protected]> Sat, 6 Sep 2008 21:09:10 -0500
| Newsgroups | gmane.comp.python.formencode |
|---|---|
| Message-ID | <[email protected]> |
Matthew,
In ascending order of significance:
First, starting with 2.5, you don't need to import the time module. You can
just write "return datetime.datetime.strptime(value, datefmt).date()".
Second, it looks like your from_python() is broken as written.
Third, I usually prefer to extend validators.DateConverter, rather than
replace it, in keeping with other parts of FormEncode. For this I employ the
builtin super() command, e.g.:
<code>
class WorseDateConverter(validators.DateConverter):
"""
Accepts '-' or '/' as delimiters.
"""
month_style = 'dd/mm/yyyy'
def _to_python(self, value, state):
value = value.replace('-', '/')
return super(WorseDateConverter, self)._to_python(value, state)
</code>
This allows me just to free-ride on more robustly tested code (i.e. said
enormous regexes).
Fourth, I too have wondered at DateConverter's lack of support for ISO 8601
format. I've knocked up stuff like this:
<code>
class IsoFormatDateConverter(validators.DateConverter):
"""
Like formencode.validators.DateConverter, but accepts ISO 8601 YYYY-mm-dd
"""
month_style = 'dd/mm/yyyy'
regex = re.compile('\d{8,8}')
def _to_python(self, value, state):
# Transform from extended to basic format (yyyymmdd...)
value = value.replace('-', '')
try:
value = value[:8]
assert self.regex.match(value)
except:
raise Invalid(("Input must be ISO 8601 format, not %s" % value),
value, state)
# Transform to 'dd/mm/yyyy'
value = '/'.join((value[6:8], value[4:6], value[:4]))
# Run superclass validation on preprocessed value
return super(IsoFormatDateConverter, self)._to_python(value, state)
</code>
On Saturday 06 September 2008 19:45:34 Matthew Wilson wrote:
> Hi, I needed a way to convert some strings into dates, but the strings
> wouldn't be in the formats acceptable to the current dateconverter
> validator.
>
> Originally, I tried looking into the dateconverter so I could add
> another date format that it could support, but then I got scared by
> those enormous regular expressions and decided to go with this
> approach. Anyhow, feedback is welcome.
>
> from time import strptime
> from formencode import Invalid
> from formencode.validators import FancyValidator
>
> class WorseDateConverter(FancyValidator):
>
> """
> Requires a list of valid date format strings.
>
> >>> wdc = WorseDateConverter(['%m-%d-%Y', '%m/%d/%Y', '%Y-%m-%d'])
> >>> wdc.to_python('09-06-2008')
>
> datetime.date(2008, 9, 6)
>
> >>> wdc.to_python('09/06/2008')
>
> datetime.date(2008, 9, 6)
>
> >>> wdc.to_python('2008-09-06')
>
> datetime.date(2008, 9, 6)
>
> >>> wdc.to_python('2008/09/06') # slashes instead of dashes.
>
> Traceback (most recent call last):
> ...
> Invalid: I couldn't parse 2008/09/06 with any of my formats!
> """
>
> def __init__(self, dateformats):
> self.dateformats = dateformats
>
> def to_python(self, value, state=None):
>
> for datefmt in self.dateformats:
>
> try:
> tt = strptime(value, datefmt)
> return date(tt.tm_year, tt.tm_mon, tt.tm_mday)
>
> except ValueError:
> pass
>
> else:
> msg = ("I couldn't parse %s with any of my formats!"
> % (value))
>
> raise Invalid(msg, value, state)
>
> def from_python(self, value, state=None):
> return value.strftime(self.datefmt)
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/