Ticket #1443: datetime_pre_1900.2.2.patch
File datetime_pre_1900.2.2.patch, 17.1 KB (added by , 18 years ago) |
---|
-
django/core/validators.py
132 132 # Could use time.strptime here and catch errors, but datetime.date below 133 133 # produces much friendlier error messages. 134 134 year, month, day = map(int, date_string.split('-')) 135 # This check is needed because strftime is used when saving the date136 # value to the database, and strftime requires that the year be >=1900.137 if year < 1900:138 raise ValidationError, gettext('Year must be 1900 or later.')139 135 try: 140 136 date(year, month, day) 141 137 except ValueError, e: -
django/db/backends/util.py
1 1 import datetime 2 from django.utils import datetime_pg 2 3 from time import time 3 4 4 5 class CursorDebugWrapper(object): … … 43 44 ############################################### 44 45 45 46 def typecast_date(s): 46 return s and datetime .date(*map(int, s.split('-'))) or None # returns None if s is null47 return s and datetime_pg.date(*map(int, s.split('-'))) or None # returns None if s is null 47 48 48 49 def typecast_time(s): # does NOT store time zone information 49 50 if not s: return None … … 77 78 seconds, microseconds = seconds.split('.') 78 79 else: 79 80 microseconds = '0' 80 return datetime .datetime(int(dates[0]), int(dates[1]), int(dates[2]),81 return datetime_pg.datetime(int(dates[0]), int(dates[1]), int(dates[2]), 81 82 int(times[0]), int(times[1]), int(seconds), int(float('.'+microseconds) * 1000000)) 82 83 83 84 def typecast_boolean(s): -
django/db/models/fields/__init__.py
8 8 from django.utils.text import capfirst 9 9 from django.utils.translation import gettext, gettext_lazy 10 10 import datetime, os, time 11 from django.utils import datetime_pg 11 12 12 13 class NOT_PROVIDED: 13 14 pass … … 404 405 Field.__init__(self, verbose_name, name, **kwargs) 405 406 406 407 def to_python(self, value): 407 if isinstance(value, datetime.datetime): 408 return value.date() 409 if isinstance(value, datetime.date): 408 if isinstance(value, datetime_pg.date): 410 409 return value 410 if isinstance(value, (datetime.date, datetime.datetime)): 411 return datetime_pg.new_date_pg(value) 411 412 validators.isValidANSIDate(value, None) 412 413 try: 413 return datetime .date(*time.strptime(value, '%Y-%m-%d')[:3])414 return datetime_pg.date(*time.strptime(value, '%Y-%m-%d')[:3]) 414 415 except ValueError: 415 416 raise validators.ValidationError, gettext('Enter a valid date in YYYY-MM-DD format.') 416 417 … … 461 462 462 463 class DateTimeField(DateField): 463 464 def to_python(self, value): 464 if isinstance(value, datetime .datetime):465 if isinstance(value, datetime_pg.datetime): 465 466 return value 466 if isinstance(value, datetime.date):467 return datetime .datetime(value.year, value.month, value.day)467 if isinstance(value, (datetime.date, datetime.datetime)): 468 return datetime_pg.new_datetime_pg(value) 468 469 try: # Seconds are optional, so try converting seconds first. 469 return datetime .datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6])470 return datetime_pg.datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6]) 470 471 except ValueError: 471 472 try: # Try without seconds. 472 return datetime .datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5])473 return datetime_pg.datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5]) 473 474 except ValueError: # Try without hour/minutes/seconds. 474 475 try: 475 return datetime .datetime(*time.strptime(value, '%Y-%m-%d')[:3])476 return datetime_pg.datetime(*time.strptime(value, '%Y-%m-%d')[:3]) 476 477 except ValueError: 477 478 raise validators.ValidationError, gettext('Enter a valid date/time in YYYY-MM-DD HH:MM format.') 478 479 … … 508 509 d = new_data.get(date_field, None) 509 510 t = new_data.get(time_field, None) 510 511 if d is not None and t is not None: 511 return datetime .datetime.combine(d, t)512 return datetime_pg.datetime.combine(d, t) 512 513 return self.get_default() 513 514 514 515 def flatten_data(self,follow, obj = None): -
django/oldforms/__init__.py
3 3 from django.utils.html import escape 4 4 from django.conf import settings 5 5 from django.utils.translation import gettext, ngettext 6 from django.utils import datetime_pg 6 7 7 8 FORM_FIELD_ID_PREFIX = 'id_' 8 9 … … 809 810 import time, datetime 810 811 try: 811 812 time_tuple = time.strptime(data, '%Y-%m-%d') 812 return datetime .date(*time_tuple[0:3])813 return datetime_pg.date(*time_tuple[0:3]) 813 814 except (ValueError, TypeError): 814 815 return None 815 816 html2python = staticmethod(html2python) -
django/utils/datetime_pg.py
1 # Python's datetime strftime doesn't handle dates before 1900. 2 # These classes override date and datetime to support the formatting of a date 3 # through its full "proleptic Gregorian" date range. 4 # 5 # Based on code submitted to comp.lang.python by Andrew Dalke 6 # 7 # >>> date_pg(1850, 8, 2).strftime("%Y/%M/%d was a %A") 8 # '1850/08/02 was a Friday' 9 # >>> 10 11 from datetime import date as real_date, datetime as real_datetime 12 import time 13 import re 14 15 16 class date_pg(real_date): 17 def strftime(self, fmt): 18 return strftime(self, fmt) 19 date = date_pg 20 21 22 class datetime_pg(real_datetime): 23 def strftime(self, fmt): 24 return strftime(self, fmt) 25 def combine(self, date, time): 26 return datetime_pg(date.year, date.month, date.day, time.hour, time.minute, time.microsecond, time.tzinfo) 27 datetime = datetime_pg 28 29 30 def new_date_pg(d): 31 """ Generate a date_pg from a datetime.date object """ 32 return date_pg(d.year, d.month, d.day) 33 34 def new_datetime_pg(d): 35 """ Generate a datetime_pg from a datetime.date or datetime.datetime object """ 36 kw = [d.year, d.month, d.day] 37 if isinstance(d, real_datetime): 38 kw.extend([d.hour, d.minute, d.second, d.microsecond, d.tzinfo]) 39 return datetime_pg(*kw) 40 41 42 # No support for strftime's "%s" or "%y". 43 # Allowed if there's an even number of "%"s because they are escaped. 44 _illegal_formatting = re.compile(r"((^|[^%])(%%)*%[sy])") 45 46 def _findall(text, substr): 47 # Also finds overlaps 48 sites = [] 49 i = 0 50 while 1: 51 j = text.find(substr, i) 52 if j == -1: 53 break 54 sites.append(j) 55 i=j+1 56 return sites 57 58 def strftime(dt, fmt): 59 if dt.year >= 1900: 60 return super(type(dt), dt).strftime(fmt) 61 illegal_formatting = _illegal_formatting.search(fmt) 62 if illegal_formatting: 63 raise TypeError("strftime of dates before 1900 does not handle" + illegal_formatting.group(0)) 64 65 year = dt.year 66 # For every non-leap year century, advance by 67 # 6 years to get into the 28-year repeat cycle 68 delta = 2000 - year 69 off = 6*(delta // 100 + delta // 400) 70 year = year + off 71 72 # Move to around the year 2000 73 year = year + ((2000 - year)//28)*28 74 timetuple = dt.timetuple() 75 s1 = time.strftime(fmt, (year,) + timetuple[1:]) 76 sites1 = _findall(s1, str(year)) 77 78 s2 = time.strftime(fmt, (year+28,) + timetuple[1:]) 79 sites2 = _findall(s2, str(year+28)) 80 81 sites = [] 82 for site in sites1: 83 if site in sites2: 84 sites.append(site) 85 86 s = s1 87 syear = "%4d" % (dt.year,) 88 for site in sites: 89 s = s[:site] + syear + s[site+4:] 90 return s -
tests/modeltests/basic/models.py
19 19 [] 20 20 21 21 # Create an Article. 22 >>> from d atetimeimport datetime22 >>> from django.utils.datetime_pg import datetime 23 23 >>> a = Article(id=None, headline='Area man programs in Python', pub_date=datetime(2005, 7, 28)) 24 24 25 25 # Save it into the database. You have to call save() explicitly. … … 33 33 >>> a.headline 34 34 'Area man programs in Python' 35 35 >>> a.pub_date 36 datetime .datetime(2005, 7, 28, 0, 0)36 datetime_pg(2005, 7, 28, 0, 0) 37 37 38 38 # Change values by changing the attributes, then calling save(). 39 39 >>> a.headline = 'Area woman programs in Python' … … 101 101 >>> a2.headline 102 102 'Second article' 103 103 >>> a2.pub_date 104 datetime .datetime(2005, 7, 29, 0, 0)104 datetime_pg(2005, 7, 29, 0, 0) 105 105 106 106 # ...or, you can use keyword arguments. 107 107 >>> a3 = Article(id=None, headline='Third article', pub_date=datetime(2005, 7, 30)) … … 111 111 >>> a3.headline 112 112 'Third article' 113 113 >>> a3.pub_date 114 datetime .datetime(2005, 7, 30, 0, 0)114 datetime_pg(2005, 7, 30, 0, 0) 115 115 116 116 # You can also mix and match position and keyword arguments, but be sure not to 117 117 # duplicate field information. … … 146 146 >>> a7 = Article(headline='Article 7', pub_date=datetime(2005, 7, 31, 12, 30)) 147 147 >>> a7.save() 148 148 >>> Article.objects.get(id__exact=7).pub_date 149 datetime .datetime(2005, 7, 31, 12, 30)149 datetime_pg(2005, 7, 31, 12, 30) 150 150 151 151 >>> a8 = Article(headline='Article 8', pub_date=datetime(2005, 7, 31, 12, 30, 45)) 152 152 >>> a8.save() 153 153 >>> Article.objects.get(id__exact=8).pub_date 154 datetime .datetime(2005, 7, 31, 12, 30, 45)154 datetime_pg(2005, 7, 31, 12, 30, 45) 155 155 >>> a8.id 156 156 8L 157 157 … … 177 177 178 178 # dates() returns a list of available dates of the given scope for the given field. 179 179 >>> Article.objects.dates('pub_date', 'year') 180 [datetime .datetime(2005, 1, 1, 0, 0)]180 [datetime_pg(2005, 1, 1, 0, 0)] 181 181 >>> Article.objects.dates('pub_date', 'month') 182 [datetime .datetime(2005, 7, 1, 0, 0)]182 [datetime_pg(2005, 7, 1, 0, 0)] 183 183 >>> Article.objects.dates('pub_date', 'day') 184 [datetime .datetime(2005, 7, 28, 0, 0), datetime.datetime(2005, 7, 29, 0, 0), datetime.datetime(2005, 7, 30, 0, 0), datetime.datetime(2005, 7, 31, 0, 0)]184 [datetime_pg(2005, 7, 28, 0, 0), datetime_pg(2005, 7, 29, 0, 0), datetime_pg(2005, 7, 30, 0, 0), datetime_pg(2005, 7, 31, 0, 0)] 185 185 >>> Article.objects.dates('pub_date', 'day', order='ASC') 186 [datetime .datetime(2005, 7, 28, 0, 0), datetime.datetime(2005, 7, 29, 0, 0), datetime.datetime(2005, 7, 30, 0, 0), datetime.datetime(2005, 7, 31, 0, 0)]186 [datetime_pg(2005, 7, 28, 0, 0), datetime_pg(2005, 7, 29, 0, 0), datetime_pg(2005, 7, 30, 0, 0), datetime_pg(2005, 7, 31, 0, 0)] 187 187 >>> Article.objects.dates('pub_date', 'day', order='DESC') 188 [datetime .datetime(2005, 7, 31, 0, 0), datetime.datetime(2005, 7, 30, 0, 0), datetime.datetime(2005, 7, 29, 0, 0), datetime.datetime(2005, 7, 28, 0, 0)]188 [datetime_pg(2005, 7, 31, 0, 0), datetime_pg(2005, 7, 30, 0, 0), datetime_pg(2005, 7, 29, 0, 0), datetime_pg(2005, 7, 28, 0, 0)] 189 189 190 190 # dates() requires valid arguments. 191 191 … … 213 213 # result one at a time, to save memory. 214 214 >>> for a in Article.objects.dates('pub_date', 'day', order='DESC').iterator(): 215 215 ... print repr(a) 216 datetime .datetime(2005, 7, 31, 0, 0)217 datetime .datetime(2005, 7, 30, 0, 0)218 datetime .datetime(2005, 7, 29, 0, 0)219 datetime .datetime(2005, 7, 28, 0, 0)216 datetime_pg(2005, 7, 31, 0, 0) 217 datetime_pg(2005, 7, 30, 0, 0) 218 datetime_pg(2005, 7, 29, 0, 0) 219 datetime_pg(2005, 7, 28, 0, 0) 220 220 221 221 # You can combine queries with & and |. 222 222 >>> s1 = Article.objects.filter(id__exact=1) … … 325 325 >>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) 326 326 >>> a9.save() 327 327 >>> Article.objects.get(id__exact=9).pub_date 328 datetime .datetime(2005, 7, 31, 12, 30, 45, 180)328 datetime_pg(2005, 7, 31, 12, 30, 45, 180) 329 329 """ 330 330 331 331 if building_docs or settings.DATABASE_ENGINE == 'mysql': … … 335 335 >>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) 336 336 >>> a9.save() 337 337 >>> Article.objects.get(id__exact=9).pub_date 338 datetime .datetime(2005, 7, 31, 12, 30, 45)338 datetime_pg(2005, 7, 31, 12, 30, 45) 339 339 """ 340 340 341 341 __test__['API_TESTS'] += """ -
tests/modeltests/manipulators/models.py
87 87 >>> a2 88 88 <Album: Ultimate Ella> 89 89 >>> a2.release_date 90 date time.date(2005, 2, 13)90 date_pg(2005, 2, 13) 91 91 """} -
tests/modeltests/or_lookups/models.py
85 85 3 86 86 87 87 >>> list(Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')).values()) 88 [{'headline': 'Hello and goodbye', 'pub_date': datetime .datetime(2005, 11, 29, 0, 0), 'id': 3}]88 [{'headline': 'Hello and goodbye', 'pub_date': datetime_pg(2005, 11, 29, 0, 0), 'id': 3}] 89 89 90 90 >>> Article.objects.filter(Q(headline__startswith='Hello')).in_bulk([1,2]) 91 91 {1: <Article: Hello>} -
tests/modeltests/reserved_names/models.py
49 49 [<Thing: a>, <Thing: h>] 50 50 51 51 >>> Thing.objects.dates('where', 'year') 52 [datetime .datetime(2005, 1, 1, 0, 0), datetime.datetime(2006, 1, 1, 0, 0)]52 [datetime_pg(2005, 1, 1, 0, 0), datetime_pg(2006, 1, 1, 0, 0)] 53 53 54 54 >>> Thing.objects.filter(where__month=1) 55 55 [<Thing: a>] -
tests/modeltests/validation/models.py
94 94 >>> p.validate() 95 95 {} 96 96 >>> p.birthdate 97 date time.date(2000, 5, 3)97 date_pg(2000, 5, 3) 98 98 99 99 >>> p = Person(**dict(valid_params, birthdate=datetime.datetime(2000, 5, 3))) 100 100 >>> p.validate() 101 101 {} 102 102 >>> p.birthdate 103 date time.date(2000, 5, 3)103 date_pg(2000, 5, 3) 104 104 105 105 >>> p = Person(**dict(valid_params, birthdate='2000-05-03')) 106 106 >>> p.validate() 107 107 {} 108 108 >>> p.birthdate 109 date time.date(2000, 5, 3)109 date_pg(2000, 5, 3) 110 110 111 111 >>> p = Person(**dict(valid_params, birthdate='2000-5-3')) 112 112 >>> p.validate() 113 113 {} 114 114 >>> p.birthdate 115 date time.date(2000, 5, 3)115 date_pg(2000, 5, 3) 116 116 117 117 >>> p = Person(**dict(valid_params, birthdate='foo')) 118 118 >>> p.validate() … … 122 122 >>> p.validate() 123 123 {} 124 124 >>> p.favorite_moment 125 datetime .datetime(2002, 4, 3, 13, 23)125 datetime_pg(2002, 4, 3, 13, 23) 126 126 127 127 >>> p = Person(**dict(valid_params, favorite_moment=datetime.datetime(2002, 4, 3))) 128 128 >>> p.validate() 129 129 {} 130 130 >>> p.favorite_moment 131 datetime .datetime(2002, 4, 3, 0, 0)131 datetime_pg(2002, 4, 3, 0, 0) 132 132 133 133 >>> p = Person(**dict(valid_params, email='john@example.com')) 134 134 >>> p.validate() -
tests/regressiontests/datetime_pg/tests.py
1 r""" 2 >>> original_datetime(*more_recent) == datetime(*more_recent) 3 True 4 >>> original_datetime(*really_old) == datetime(*really_old) 5 True 6 >>> original_date(*more_recent) == date(*more_recent) 7 True 8 >>> original_date(*really_old) == date(*really_old) 9 True 10 11 >>> original_date(*just_safe).strftime('%Y-%m-%d') == date(*just_safe).strftime('%Y-%m-%d') 12 True 13 >>> original_datetime(*just_safe).strftime('%Y-%m-%d') == datetime(*just_safe).strftime('%Y-%m-%d') 14 True 15 16 >>> date(*just_unsafe[:3]).strftime('%Y-%m-%d (weekday %w)') 17 '1899-12-31 (weekday 0)' 18 >>> date(*just_safe).strftime('%Y-%m-%d (weekday %w)') 19 '1900-01-01 (weekday 1)' 20 21 >>> datetime(*just_unsafe).strftime('%Y-%m-%d %H:%M:%S (weekday %w)') 22 '1899-12-31 23:59:59 (weekday 0)' 23 >>> datetime(*just_safe).strftime('%Y-%m-%d %H:%M:%S (weekday %w)') 24 '1900-01-01 00:00:00 (weekday 1)' 25 26 >>> date(*just_safe).strftime('%y') # %y will error before this date 27 '00' 28 >>> datetime(*just_safe).strftime('%y') 29 '00' 30 """ 31 32 from datetime import date as original_date, datetime as original_datetime 33 from django.utils.datetime_pg import date, datetime 34 35 just_safe = (1900, 1, 1) 36 just_unsafe = (1899, 12, 31, 23, 59, 59) 37 really_old = (20, 1, 1) 38 more_recent = (2006, 1, 1)