[Erp5-report] r39374 yo - /erp5/trunk/products/ERP5/Document/Alarm.py
nobody at svn.erp5.org
nobody at svn.erp5.org
Wed Oct 20 10:08:41 CEST 2010
Author: yo
Date: Wed Oct 20 10:08:41 2010
New Revision: 39374
URL: http://svn.erp5.org?rev=39374&view=rev
Log:
This is a fix for the long-living bug that the periodicity mixin
does not work appropriately with daylight savings / summer time.
Modified:
erp5/trunk/products/ERP5/Document/Alarm.py
Modified: erp5/trunk/products/ERP5/Document/Alarm.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/Alarm.py?rev=39374&r1=39373&r2=39374&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/Alarm.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/Alarm.py [utf8] Wed Oct 20 10:08:41 2010
@@ -130,6 +130,48 @@ class PeriodicityMixin:
elif len(periodicity_month_list) > 0:
return date.month() in periodicity_month_list
+ def _getTimezone(self, date):
+ # This method provides an utility to deal with a timezone as a workaround.
+ # This is necessary because DateTime does not respect the real timezone
+ # such as Europe/Paris, but only stores a difference from GMT such as
+ # GMT+1, thus it does not work nicely with daylight savings.
+ if date.tzoffset() == 0:
+ # Looks like using GMT.
+ return date.timezone()
+ return None
+
+ def _getNextDay(self, date, timezone):
+ if timezone is not None:
+ new_date = DateTime(date.timeTime() + 86400.0, timezone)
+ else:
+ new_date = DateTime(date.timeTime() + 86400.0)
+
+ # Due to daylight savings, 24 hours later does not always mean that
+ # it's next day.
+ while new_date.day() == date.day():
+ if timezone is not None:
+ new_date = DateTime(new_date.timeTime() + 3600.0, timezone)
+ else:
+ new_date = DateTime(new_date.timeTime() + 3600.0)
+ return DateTime(new_date.year(), new_date.month(), new_date.day(),
+ 0, 0, 0, timezone)
+
+ def _getNextHour(self, date, timezone):
+ if timezone is not None:
+ new_date = DateTime(date.timeTime() + 3600.0, timezone)
+ else:
+ new_date = DateTime(date.timeTime() + 3600.0)
+ return DateTime(new_date.year(), new_date.month(), new_date.day(),
+ new_date.hour(), 0, 0, timezone)
+
+ def _getNextMinute(self, date, timezone):
+ if timezone is not None:
+ new_date = DateTime(date.timeTime() + 60.0, timezone)
+ else:
+ new_date = DateTime(date.timeTime() + 60.0)
+ return DateTime(new_date.year(), new_date.month(), new_date.day(),
+ new_date.hour(), new_date.minute(), 0, timezone)
+
security.declareProtected(Permissions.AccessContentsInformation, 'getNextPeriodicalDate')
def getNextPeriodicalDate(self, current_date, next_start_date=None):
"""
@@ -159,21 +201,24 @@ class PeriodicityMixin:
and next_start_date >= periodicity_stop_date):
return None
+ timezone = self._getTimezone(next_start_date)
previous_date = next_start_date
- next_start_date = max(addToDate(next_start_date, minute=1), current_date)
+ next_start_date = max(self._getNextMinute(next_start_date, timezone),
+ current_date)
while 1:
if not self._validateMonth(next_start_date):
- next_start_date = atTheEndOfPeriod(next_start_date, 'month')
+ next_start_date = self._getNextMonth(next_start_date, timezone)
elif not (self._validateDay(next_start_date) and
self._validateWeek(next_start_date)):
- next_start_date = atTheEndOfPeriod(next_start_date, 'day')
+ next_start_date = self._getNextDay(next_start_date, timezone)
elif not self._validateMinute(next_start_date, previous_date):
- next_start_date = addToDate(next_start_date, minute=1)
+ next_start_date = self._getNextMinute(next_start_date, timezone)
elif not self._validateHour(next_start_date):
- next_start_date = addToDate(next_start_date, hour=1)
+ next_start_date = self._getNextHour(next_start_date, timezone)
else:
parts = list(next_start_date.parts())
parts[5] = previous_date.second() # XXX keep old behaviour
+ parts[6] = timezone
return DateTime(*parts)
# XXX May be we should create a Date class for following methods ???
More information about the Erp5-report
mailing list