#from TurboGears:
#Copyright (c) 2005, 2006 Kevin Dangoor and contributors. TurboGears
#is a trademark of Kevin Dangoor.
#Permission is hereby granted, free of charge, to any person obtaining
#a copy of this software and associated documentation files (the
#"Software"), to deal in the Software without restriction, including
#without limitation the rights to use, copy, modify, merge, publish,
#distribute, sublicense, and/or sell copies of the Software, and to
#permit persons to whom the Software is furnished to do so, subject to
#the following conditions:
#The above copyright notice and this permission notice shall be
#included in all copies or substantial portions of the Software.
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
#NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
#BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
#ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
#CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.
class DateTimeConverter(FancyValidator):
"""
Converts Python date and datetime objects into string representation and back.
"""
messages = {
'badFormat': 'Invalid datetime format',
'empty': 'Empty values not allowed',
}
def __init__(self, format = "%Y/%m/%d %H:%M", allow_empty = None,
*args, **kwargs):
if allow_empty is not None:
warnings.warn("Use not_empty instead of allow_empty",
DeprecationWarning, 2)
not_empty = not allow_empty
kw["not_empty"] = not_empty
super(FancyValidator, self).__init__(*args, **kwargs)
self.format = format
def _to_python(self, value, state):
""" parse a string and return a datetime object. """
if value and isinstance(value, datetime):
return value
else:
try:
tpl = time.strptime(value, self.format)
except ValueError:
raise Invalid(self.message('badFormat', state), value, state)
# shoudn't use time.mktime() because it can give OverflowError,
# depending on the date (e.g. pre 1970) and underlying C library
return datetime(year=tpl.tm_year, month=tpl.tm_mon, day=tpl.tm_mday,
hour=tpl.tm_hour, minute=tpl.tm_min, second=tpl.tm_sec)
def _from_python(self, value, state):
if not value:
return None
elif isinstance(value, datetime):
# Python stdlib can only handle dates with year greater than 1900
if value.year <= 1900:
return strftime_before1900(value, self.format)
else:
return value.strftime(self.format)
else:
return value