Changeset 8162


Ignore:
Timestamp:
15 Apr 2012, 14:04:19 (12 years ago)
Author:
uli
Message:

Support timezones in datetimes.

Location:
main/waeup.kofa/trunk/src/waeup/kofa/widgets
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/widgets/datetimewidget.py

    r8158 r8162  
    2020"""
    2121from datetime import datetime
     22from zope.datetime import parseDatetimetz, DateTimeError
    2223from zope.formlib.interfaces import ConversionError, IDisplayWidget
    2324from zope.formlib.textwidgets import (
     
    7879            context, request, *args, **kw)
    7980
     81    def _toTZValue(self, string):
     82        """Try to turn `string` into a timezone-aware datetime.
     83
     84        If the string provides no TZ info it is interpreted as
     85        localtime (server time).
     86
     87        We do this by first turning the data-part of the string (w/o
     88        TZ info) into some regular datetime (w/o TZ set), then
     89        transforming the datetime into an unambigous string again
     90        (this time with TZ info from initial string) and finally
     91        turning the unambigous string into a datetime with TZ info set
     92        (using zope.datetime.parseDatetimetz).
     93        """
     94        # Split date and tz-info. XXX: Very fragile
     95        date, tzdata = string[:19], string[19:]
     96        # Turn string representation into something non-ambigious
     97        # based on local date_format. Make sure we do not confuse
     98        # mm/dd/yy with dd/mm/yy.
     99        try:
     100            value = datetime.strptime(date, self.date_format)
     101        except (DateTimeError, ValueError, IndexError), v:
     102            # Fallback: use ISO-representation
     103            value = datetime.strptime(
     104                date, FormattedDatetimeWidget.date_format)
     105        # Create a string unambigous for parseDatetimetz and with TZ info.
     106        iso_date = value.strftime('%Y-%m-%dT%H:%M:%S')
     107        iso_date += tzdata
     108        return parseDatetimetz(iso_date)
     109
    80110    def _toFieldValue(self, input):
    81111        # In import files we can use the hash symbol at the end of a
     
    85115        if input == self._missing:
    86116            return self.context.missing_value
    87         else:
    88             try:
    89                 value = datetime.strptime(input, self.date_format)
    90             except (ValueError, IndexError), v:
    91                 try:
    92                     # Try ISO format as fallback.
    93                     # This is needed for instance during imports.
    94                     value = datetime.strptime(
    95                         input, FormattedDatetimeWidget.date_format)
    96                 except (ValueError, IndexError), v:
    97                     raise ConversionError("Invalid datetime data", v)
     117        try:
     118            value = self._toTZValue(input)
     119        except (DateTimeError, ValueError, IndexError), v:
     120            raise ConversionError("Invalid datetime data", v)
    98121        return value
    99122
  • main/waeup.kofa/trunk/src/waeup/kofa/widgets/tests/test_datetimewidget.py

    r8158 r8162  
    77from zope.interface.verify import verifyClass
    88
     9from zope.datetime import parseDatetimetz
    910from zope.formlib.tests.test_browserwidget import (
    1011    SimpleInputWidgetTest, BrowserWidgetTest, )
     
    5758    def test_getDefaultInputValue(self,
    5859            value=u'2004-03-26 12:10:20',
    59             check_value=datetime.datetime(2004, 3, 26, 12, 10, 20)):
     60            check_value = parseDatetimetz('2004-03-26 12:10:20 GMT')):
    6061        self._widget.request.form['field.foo'] = u''
    6162        self.assertRaises(WidgetInputError, self._widget.getInputValue)
Note: See TracChangeset for help on using the changeset viewer.