[Erp5-report] r18884 - /erp5/trunk/products/ERP5Type/patches/DateTimePatch.py

nobody at svn.erp5.org nobody at svn.erp5.org
Mon Jan 28 14:18:04 CET 2008


Author: nicolas
Date: Mon Jan 28 14:18:04 2008
New Revision: 18884

URL: http://svn.erp5.org?rev=18884&view=rev
Log:
Authorised date manipulation before year 1000

Modified:
    erp5/trunk/products/ERP5Type/patches/DateTimePatch.py

Modified: erp5/trunk/products/ERP5Type/patches/DateTimePatch.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/patches/DateTimePatch.py?rev=18884&r1=18883&r2=18884&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/patches/DateTimePatch.py (original)
+++ erp5/trunk/products/ERP5Type/patches/DateTimePatch.py Mon Jan 28 14:18:04 2008
@@ -28,7 +28,7 @@
 
 from DateTime import DateTime as DateTimeKlass
 import math
-from DateTime.DateTime import _calcSD, _calcDependentSecond, _calcYMDHMS
+from DateTime.DateTime import _calcSD, _calcDependentSecond, _calcYMDHMS, getDefaultDateFormat, _correctYear, _calcHMS, _calcDependentSecond2
 
 STATE_KEY = 'str'
 
@@ -53,6 +53,195 @@
   return (self._t, self._tz)
 
 DateTimeKlass.__getstate__ = DateTime__getstate__
+
+def DateTime_parse(self, st, datefmt=getDefaultDateFormat()):
+  # Parse date-time components from a string
+  month=year=tz=tm=None
+  spaces        =self.space_chars
+  intpat        =self.int_pattern
+  fltpat        =self.flt_pattern
+  wordpat       =self.name_pattern
+  delimiters    =self.delimiters
+  MonthNumbers  =self._monthmap
+  DayOfWeekNames=self._daymap
+  ValidZones    =self._tzinfo._zidx
+  TimeModifiers =['am','pm']
+
+  # Find timezone first, since it should always be the last
+  # element, and may contain a slash, confusing the parser.
+  st= st.strip()
+  sp=st.split()
+  tz=sp[-1]
+  if tz and (tz.lower() in ValidZones): st=' '.join(sp[:-1])
+  else: tz = None  # Decide later, since the default time zone
+  # could depend on the date.
+
+  ints,dels=[],[]
+  i,l=0,len(st)
+  while i < l:
+    while i < l and st[i] in spaces    : i=i+1
+    if i < l and st[i] in delimiters:
+      d=st[i]
+      i=i+1
+    else: d=''
+    while i < l and st[i] in spaces    : i=i+1
+
+    # The float pattern needs to look back 1 character, because it
+    # actually looks for a preceding colon like ':33.33'. This is
+    # needed to avoid accidentally matching the date part of a
+    # dot-separated date string such as '1999.12.31'.
+    if i > 0: b=i-1
+    else: b=i
+
+    ts_results = fltpat.match(st, b)
+    if ts_results:
+      s=ts_results.group(1)
+      i=i+len(s)
+      ints.append(float(s))
+      continue
+
+    #AJ
+    ts_results = intpat.match(st, i)
+    if ts_results:
+      s=ts_results.group(0)
+
+      ls=len(s)
+      i=i+ls
+      if (ls==4 and d and d in '+-' and
+          (len(ints) + (not not month) >= 3)):
+          tz='%s%s' % (d,s)
+      else:
+          v=int(s)
+          ints.append(v)
+      continue
+
+
+    ts_results = wordpat.match(st, i)
+    if ts_results:
+      o,s=ts_results.group(0),ts_results.group(0).lower()
+      i=i+len(s)
+      if i < l and st[i]=='.': i=i+1
+      # Check for month name:
+      if MonthNumbers.has_key(s):
+        v=MonthNumbers[s]
+        if month is None: month=v
+        else: raise SyntaxError, st
+        continue
+      # Check for time modifier:
+      if s in TimeModifiers:
+        if tm is None: tm=s
+        else: raise SyntaxError, st
+        continue
+      # Check for and skip day of week:
+      if DayOfWeekNames.has_key(s):
+        continue
+
+    raise SyntaxError, st
+
+  day=None
+  if ints[-1] > 60 and d not in ['.',':','/'] and len(ints) > 2:
+    year=ints[-1]
+    del ints[-1]
+    if month:
+      day=ints[0]
+      del ints[:1]
+    else:
+      month=ints[0]
+      day=ints[1]
+      del ints[:2]
+  elif month:
+    if len(ints) > 1:
+      if ints[0] > 31:
+        year=ints[0]
+        day=ints[1]
+      else:
+        year=ints[1]
+        day=ints[0]
+      del ints[:2]
+  elif len(ints) > 2:
+    if ints[0] > 31:
+      year=ints[0]
+      if ints[1] > 12:
+        day=ints[1]
+        month=ints[2]
+      else:
+        day=ints[2]
+        month=ints[1]
+    if ints[1] > 31:
+      year=ints[1]
+      if ints[0] > 12 and ints[2] <= 12:
+        day=ints[0]
+        month=ints[2]
+      elif ints[2] > 12 and ints[0] <= 12:
+        day=ints[2]
+        month=ints[0]
+    elif ints[2] > 31:
+      year=ints[2]
+      if ints[0] > 12:
+        day=ints[0]
+        month=ints[1]
+      else:
+        if datefmt=="us":
+          day=ints[1]
+          month=ints[0]
+        else:
+          day=ints[0]
+          month=ints[1]
+
+    elif ints[0] <= 12:
+      month=ints[0]
+      day=ints[1]
+      year=ints[2]
+    del ints[:3]
+
+  if day is None:
+    # Use today's date.
+    year,month,day = localtime(time())[:3]
+
+  year = _correctYear(year)
+  #handle dates before year 1000
+  #if year < 1000: raise SyntaxError, st
+
+  leap = year%4==0 and (year%100!=0 or year%400==0)
+  try:
+    if not day or day > self._month_len[leap][month]:
+      raise DateError, st
+  except IndexError:
+    raise DateError, st
+  tod=0
+  if ints:
+    i=ints[0]
+    # Modify hour to reflect am/pm
+    if tm and (tm=='pm') and i<12:  i=i+12
+    if tm and (tm=='am') and i==12: i=0
+    if i > 24: raise TimeError, st
+    tod = tod + int(i) * 3600
+    del ints[0]
+    if ints:
+      i=ints[0]
+      if i > 60: raise TimeError, st
+      tod = tod + int(i) * 60
+      del ints[0]
+      if ints:
+        i=ints[0]
+        if i > 60: raise TimeError, st
+        tod = tod + i
+        del ints[0]
+        if ints: raise SyntaxError,st
+
+
+  tod_int = int(math.floor(tod))
+  ms = tod - tod_int
+  hr,mn,sc = _calcHMS(tod_int, ms)
+  if not tz:
+    # Figure out what time zone it is in the local area
+    # on the given date.
+    x = _calcDependentSecond2(year,month,day,hr,mn,sc)
+    tz = self._calcTimezoneName(x, ms)
+
+  return year,month,day,hr,mn,sc,tz
+
+DateTimeKlass._parse = DateTime_parse
 
 if __name__ == '__main__':
   for i in ('2007/01/02 12:34:56.789',




More information about the Erp5-report mailing list