Mercurial > p > roundup > code
comparison roundup/date.py @ 3822:2a60b68985db
Fix arbitrary limit on dates.
Dates can now be in the year-range 1-9999 for all backends except
metakit which is still limited to 1970-2038.
| author | Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net> |
|---|---|
| date | Fri, 09 Mar 2007 10:25:10 +0000 |
| parents | 842f1a292ff8 |
| children | 7cda5b4daa91 |
comparison
equal
deleted
inserted
replaced
| 3821:5ed4c9d30148 | 3822:2a60b68985db |
|---|---|
| 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.89 2006-12-28 22:38:02 richard Exp $ | 18 # $Id: date.py,v 1.90 2007-03-09 10:25:09 schlatterbeck Exp $ |
| 19 | 19 |
| 20 """Date, time and time interval handling. | 20 """Date, time and time interval handling. |
| 21 """ | 21 """ |
| 22 __docformat__ = 'restructuredtext' | 22 __docformat__ = 'restructuredtext' |
| 23 | 23 |
| 261 self.set(spec, offset=offset, add_granularity=add_granularity) | 261 self.set(spec, offset=offset, add_granularity=add_granularity) |
| 262 return | 262 return |
| 263 elif isinstance(spec, datetime.datetime): | 263 elif isinstance(spec, datetime.datetime): |
| 264 # Python 2.3+ datetime object | 264 # Python 2.3+ datetime object |
| 265 y,m,d,H,M,S,x,x,x = spec.timetuple() | 265 y,m,d,H,M,S,x,x,x = spec.timetuple() |
| 266 if y < 1970: raise ValueError, 'year must be > 1970' | |
| 267 S += spec.microsecond/1000000. | 266 S += spec.microsecond/1000000. |
| 268 spec = (y,m,d,H,M,S,x,x,x) | 267 spec = (y,m,d,H,M,S,x,x,x) |
| 269 elif hasattr(spec, 'tuple'): | 268 elif hasattr(spec, 'tuple'): |
| 270 spec = spec.tuple() | 269 spec = spec.tuple() |
| 271 elif isinstance(spec, Date): | 270 elif isinstance(spec, Date): |
| 272 spec = spec.get_tuple() | 271 spec = spec.get_tuple() |
| 273 try: | 272 try: |
| 274 y,m,d,H,M,S,x,x,x = spec | 273 y,m,d,H,M,S,x,x,x = spec |
| 275 if y < 1970: raise ValueError, 'year must be > 1970' | |
| 276 frac = S - int(S) | 274 frac = S - int(S) |
| 277 self.year, self.month, self.day, self.hour, self.minute, \ | 275 self.year, self.month, self.day, self.hour, self.minute, \ |
| 278 self.second = _local_to_utc(y, m, d, H, M, S, offset) | 276 self.second = _local_to_utc(y, m, d, H, M, S, offset) |
| 279 # we lost the fractional part | 277 # we lost the fractional part |
| 280 self.second = self.second + frac | 278 self.second = self.second + frac |
| 307 | 305 |
| 308 if add_granularity: | 306 if add_granularity: |
| 309 _add_granularity(info, 'SMHdmyab') | 307 _add_granularity(info, 'SMHdmyab') |
| 310 | 308 |
| 311 # get the current date as our default | 309 # get the current date as our default |
| 312 ts = time.time() | 310 dt = datetime.datetime.utcnow() |
| 313 frac = ts - int(ts) | 311 y,m,d,H,M,S,x,x,x = dt.timetuple() |
| 314 y,m,d,H,M,S,x,x,x = time.gmtime(ts) | 312 S += dt.microsecond/1000000. |
| 315 # gmtime loses the fractional seconds | |
| 316 S = S + frac | |
| 317 if str(S) == '60.0': S = 59.9 | |
| 318 | 313 |
| 319 # whether we need to convert to UTC | 314 # whether we need to convert to UTC |
| 320 adjust = False | 315 adjust = False |
| 321 | 316 |
| 322 if info['y'] is not None or info['a'] is not None: | 317 if info['y'] is not None or info['a'] is not None: |
| 323 if info['y'] is not None: | 318 if info['y'] is not None: |
| 324 y = int(info['y']) | 319 y = int(info['y']) |
| 325 if y < 1970: raise ValueError, 'year must be > 1970' | |
| 326 m,d = (1,1) | 320 m,d = (1,1) |
| 327 if info['m'] is not None: | 321 if info['m'] is not None: |
| 328 m = int(info['m']) | 322 m = int(info['m']) |
| 329 if info['d'] is not None: | 323 if info['d'] is not None: |
| 330 d = int(info['d']) | 324 d = int(info['d']) |
| 342 S = 0 | 336 S = 0 |
| 343 if info['S'] is not None: | 337 if info['S'] is not None: |
| 344 S = float(info['S']) | 338 S = float(info['S']) |
| 345 adjust = True | 339 adjust = True |
| 346 | 340 |
| 347 if add_granularity: | |
| 348 S = S - 1 | |
| 349 | 341 |
| 350 # now handle the adjustment of hour | 342 # now handle the adjustment of hour |
| 351 frac = S - int(S) | 343 frac = S - int(S) |
| 352 ts = calendar.timegm((y,m,d,H,M,S,0,0,0)) | 344 dt = datetime.datetime(y,m,d,H,M,int(S), int(frac * 1000000.)) |
| 353 y, m, d, H, M, S, x, x, x = time.gmtime(ts) | 345 if add_granularity: |
| 346 dt = dt - datetime.timedelta(seconds=1) | |
| 347 y, m, d, H, M, S, x, x, x = dt.timetuple() | |
| 354 if adjust: | 348 if adjust: |
| 355 y, m, d, H, M, S = _local_to_utc(y, m, d, H, M, S, offset) | 349 y, m, d, H, M, S = _local_to_utc(y, m, d, H, M, S, offset) |
| 356 self.year, self.month, self.day, self.hour, self.minute, \ | 350 self.year, self.month, self.day, self.hour, self.minute, \ |
| 357 self.second = y, m, d, H, M, S | 351 self.second = y, m, d, H, M, S |
| 358 # we lost the fractional part along the way | 352 # we lost the fractional part along the way |
| 359 self.second = self.second + frac | 353 self.second += dt.microsecond/1000000. |
| 360 if str(self.second) == '60.0': self.second = 59.9 | |
| 361 | 354 |
| 362 if info.get('o', None): | 355 if info.get('o', None): |
| 363 try: | 356 try: |
| 364 self.applyInterval(Interval(info['o'], allowdate=0)) | 357 self.applyInterval(Interval(info['o'], allowdate=0)) |
| 365 except ValueError: | 358 except ValueError: |
| 491 def __str__(self): | 484 def __str__(self): |
| 492 """Return this date as a string in the yyyy-mm-dd.hh:mm:ss format.""" | 485 """Return this date as a string in the yyyy-mm-dd.hh:mm:ss format.""" |
| 493 return self.formal() | 486 return self.formal() |
| 494 | 487 |
| 495 def formal(self, sep='.', sec='%02d'): | 488 def formal(self, sep='.', sec='%02d'): |
| 496 f = '%%4d-%%02d-%%02d%s%%02d:%%02d:%s'%(sep, sec) | 489 f = '%%04d-%%02d-%%02d%s%%02d:%%02d:%s'%(sep, sec) |
| 497 return f%(self.year, self.month, self.day, self.hour, self.minute, | 490 return f%(self.year, self.month, self.day, self.hour, self.minute, |
| 498 self.second) | 491 self.second) |
| 499 | 492 |
| 500 def pretty(self, format='%d %B %Y'): | 493 def pretty(self, format='%d %B %Y'): |
| 501 ''' print up the date date using a pretty format... | 494 ''' print up the date date using a pretty format... |
| 502 | 495 |
| 503 Note that if the day is zero, and the day appears first in the | 496 Note that if the day is zero, and the day appears first in the |
| 504 format, then the day number will be removed from output. | 497 format, then the day number will be removed from output. |
| 505 ''' | 498 ''' |
| 506 # Python2.4 strftime() enforces the non-zero-ness of the day-of-year | 499 dt = datetime.datetime(self.year, self.month, self.day, self.hour, |
| 507 # component of the time tuple, so we need to figure it out | 500 self.minute, int(self.second), |
| 508 t = (self.year, self.month, self.day, self.hour, self.minute, | 501 (self.second - int (self.second)) * 1000000.) |
| 509 int(self.second), 0, 0, 0) | 502 str = dt.strftime(format) |
| 510 t = calendar.timegm(t) | |
| 511 t = time.gmtime(t) | |
| 512 str = time.strftime(format, t) | |
| 513 | 503 |
| 514 # handle zero day by removing it | 504 # handle zero day by removing it |
| 515 if format.startswith('%d') and str[0] == '0': | 505 if format.startswith('%d') and str[0] == '0': |
| 516 return ' ' + str[1:] | 506 return ' ' + str[1:] |
| 517 return str | 507 return str |
| 533 def get_tuple(self): | 523 def get_tuple(self): |
| 534 return (self.year, self.month, self.day, self.hour, self.minute, | 524 return (self.year, self.month, self.day, self.hour, self.minute, |
| 535 self.second, 0, 0, 0) | 525 self.second, 0, 0, 0) |
| 536 | 526 |
| 537 def serialise(self): | 527 def serialise(self): |
| 538 return '%4d%02d%02d%02d%02d%06.3f'%(self.year, self.month, | 528 return '%04d%02d%02d%02d%02d%06.3f'%(self.year, self.month, |
| 539 self.day, self.hour, self.minute, self.second) | 529 self.day, self.hour, self.minute, self.second) |
| 540 | 530 |
| 541 def timestamp(self): | 531 def timestamp(self): |
| 542 ''' return a UNIX timestamp for this date ''' | 532 ''' return a UNIX timestamp for this date ''' |
| 543 frac = self.second - int(self.second) | 533 frac = self.second - int(self.second) |
