comparison roundup/date.py @ 1896:b3f63a0615db maint-0.6

backport of Date arithmetic fixes from trunk
author Anthony Baxter <anthonybaxter@users.sourceforge.net>
date Tue, 04 Nov 2003 12:39:54 +0000
parents 2047425bf7e7
children 27b9292a2fe6
comparison
equal deleted inserted replaced
1895:11010aae4ef0 1896:b3f63a0615db
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17 # 17 #
18 # $Id: date.py,v 1.54 2003-04-23 11:48:05 richard Exp $ 18 # $Id: date.py,v 1.54.2.1 2003-11-04 12:39:54 anthonybaxter Exp $
19 19
20 __doc__ = """ 20 __doc__ = """
21 Date, time and time interval handling. 21 Date, time and time interval handling.
22 """ 22 """
23 23
202 while month < 1 or month > 12: 202 while month < 1 or month > 12:
203 if month < 1: year -= 1; month += 12 203 if month < 1: year -= 1; month += 12
204 if month > 12: year += 1; month -= 12 204 if month > 12: year += 1; month -= 12
205 205
206 # now do the days, now that we know what month we're in 206 # now do the days, now that we know what month we're in
207 mdays = calendar.mdays 207 def get_mdays(year,month):
208 if month == 2 and calendar.isleap(year): month_days = 29 208 if month == 2 and calendar.isleap(year): return 29
209 else: month_days = mdays[month] 209 else: return calendar.mdays[month]
210 while month < 1 or month > 12 or day < 0 or day > month_days: 210
211 while month < 1 or month > 12 or day < 0 or day > get_mdays(year,month):
211 # now to day under/over 212 # now to day under/over
212 if day < 0: month -= 1; day += month_days 213 if day < 0:
213 elif day > month_days: month += 1; day -= month_days 214 # When going backwards, decrement month, then increment days
215 month -= 1
216 day += get_mdays(year,month)
217 elif day > get_mdays(year,month):
218 # When going forwards, decrement days, then increment month
219 day -= get_mdays(year,month)
220 month += 1
214 221
215 # possibly fix up the month so we're within range 222 # possibly fix up the month so we're within range
216 while month < 1 or month > 12: 223 while month < 1 or month > 12:
217 if month < 1: year -= 1; month += 12 224 if month < 1: year -= 1; month += 12 ; day += 31
218 if month > 12: year += 1; month -= 12 225 if month > 12: year += 1; month -= 12
219 226
220 # re-figure the number of days for this month
221 if month == 2 and calendar.isleap(year): month_days = 29
222 else: month_days = mdays[month]
223 return (year, month, day, hour, minute, second, 0, 0, 0) 227 return (year, month, day, hour, minute, second, 0, 0, 0)
228
229 def differenceDate(self, other):
230 "Return the difference between this date and another date"
224 231
225 def applyInterval(self, interval): 232 def applyInterval(self, interval):
226 ''' Apply the interval to this date 233 ''' Apply the interval to this date
227 ''' 234 '''
228 self.year, self.month, self.day, self.hour, self.minute, \ 235 self.year, self.month, self.day, self.hour, self.minute, \
244 other.sign *= -1 251 other.sign *= -1
245 return self.__add__(other) 252 return self.__add__(other)
246 253
247 assert isinstance(other, Date), 'May only subtract Dates or Intervals' 254 assert isinstance(other, Date), 'May only subtract Dates or Intervals'
248 255
249 # TODO this code will fall over laughing if the dates cross 256 return self.dateDelta(other)
250 # leap years, phases of the moon, .... 257
258 def dateDelta(self, other):
259 """ Produce an Interval of the difference between this date
260 and another date. Only returns days:hours:minutes:seconds.
261 """
262 # Returning intervals larger than a day is almost
263 # impossible - months, years, weeks, are all so imprecise.
251 a = calendar.timegm((self.year, self.month, self.day, self.hour, 264 a = calendar.timegm((self.year, self.month, self.day, self.hour,
252 self.minute, self.second, 0, 0, 0)) 265 self.minute, self.second, 0, 0, 0))
253 b = calendar.timegm((other.year, other.month, other.day, 266 b = calendar.timegm((other.year, other.month, other.day,
254 other.hour, other.minute, other.second, 0, 0, 0)) 267 other.hour, other.minute, other.second, 0, 0, 0))
255 diff = a - b 268 diff = a - b
256 if diff < 0: 269 if diff > 0:
257 sign = 1 270 sign = 1
271 else:
272 sign = -1
258 diff = -diff 273 diff = -diff
259 else:
260 sign = -1
261 S = diff%60 274 S = diff%60
262 M = (diff/60)%60 275 M = (diff/60)%60
263 H = (diff/(60*60))%60 276 H = (diff/(60*60))%24
264 if H>1: S = 0 277 d = diff/(24*60*60)
265 d = (diff/(24*60*60))%30 278 return Interval((0, 0, d, H, M, S), sign=sign)
266 if d>1: H = S = M = 0
267 m = (diff/(30*24*60*60))%12
268 if m>1: H = S = M = 0
269 y = (diff/(365*24*60*60))
270 if y>1: d = H = S = M = 0
271 return Interval((y, m, d, H, M, S), sign=sign)
272 279
273 def __cmp__(self, other): 280 def __cmp__(self, other):
274 """Compare this date to another date.""" 281 """Compare this date to another date."""
275 if other is None: 282 if other is None:
276 return 1 283 return 1

Roundup Issue Tracker: http://roundup-tracker.org/