Anonymous avatar Anonymous committed 6eac1a6

Modified date.from_xml, datetime.from_xml to take time zones into account - bug 9.

Comments (0)

Files changed (2)

 """
 from . import xmlnamespace
 from decimal import Decimal
-from datetime import date, datetime
+from datetime import date, datetime, timedelta
 import xml.etree.cElementTree as etree
 import base64
 import sys
         if not(element.text):
             return date(1970, 1, 1)
         text = element.text
-        pos = text.find("UTC")
-        if pos != -1:
-            text = text[:pos]
-        full = datetime.strptime(text, '%Y-%m-%d')
-
-        return full.date()
+        y, m, d = text.split("-")[:3]
+        y = int(y)
+        m = int(m)
+        d = int(d[:2])
+        # ignore time zone information here
+        return  date(y, m, d)
 
 
 class XMLDateTime(XMLType):
         if not(element.text):
             return datetime(1970, 1, 1)
         text = element.text
-        pos = text.find("UTC")
-        if pos != -1:
-            text = text[:pos]
-        return datetime.strptime(text, '%Y-%m-%dT%H:%M:%S.%f')
-
+        # this way looks a bit slow, please complain if you need
+        datestr, timestr = text.split("T",1)
+        year, month, day = datestr.split("-")
+        year = int(year)
+        month = int(month)
+        day = int(day)
+        hour, minute, second = timestr.split(":", 2)
+        hour = int(hour)
+        minute = int(minute)
+        rest = second[2:]
+        second = int(second[:2])
+        fraction = 0 
+        if rest and rest[0] == ".":
+            # fraction of second
+            pos = len(rest)
+            for i in range(1,len(rest)):
+                if not rest[i].isdigit():
+                    pos = i
+                    break
+            fraction = int(float(rest[:pos])*1e6)
+            rest = rest[pos:]
+        value = datetime(year, month, day, hour, minute, second, fraction)
+        # time zone to UTC
+        if rest and (rest[0] == "+" or rest[0] == "-"):
+            zh, zm = rest.split(":",1)
+            zh = int(zh)
+            zm = int(rest[0]+zm[:2]) # add sign to minutes
+            delta = timedelta(hours = zh, minutes = zm)
+            value = value - delta
+        return value
 
 class XMLStringEnumeration(XMLType):
     _allowedValues = []

tests/test_xmltypes_primitive.py

         value = XMLDateTime().from_xml(element)
         self.assertEqual(value, datetime(1970,1,1))
 
+        element.text = "2012-01-31T10:00:00.538"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,31, 10, 0, 0, 538000))
+        element.text = "2012-01-30T10:00:00"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,30, 10, 0, 0))
+        element.text = "2012-01-20T10:00:00UTC"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,20, 10, 0, 0))
+        element.text = "2012-01-10T10:00:00Z"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,10, 10, 0, 0))
+        # with time zone - bug 9
+        element.text = "2012-01-31T10:00:00.538+02:30"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,31, 7, 30, 0, 538000))
+        element.text = "2012-01-30T01:00:00+01:30"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,29, 23, 30, 0))
+        element.text = "2012-01-31T10:00:00.538-02:30"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,31, 12, 30, 0, 538000))
+        element.text = "2012-01-31T10:00:00-01:00"
+        value = XMLDateTime().from_xml(element)
+        self.assertEqual(value, datetime(2012,01,31, 11, 00, 0))
+
     def test_date(self):
         x = datetime.now()
         x = x.date()
         value = XMLDate().from_xml(element)
         self.assertEqual(value, date(1970,1,1))
 
+        element.text = "2013-01-31UTC"
+        value = XMLDate().from_xml(element)
+        self.assertEqual(value, date(2013,01,31))
+        element.text = "2013-02-11Z"
+        value = XMLDate().from_xml(element)
+        self.assertEqual(value, date(2013,02,11))
+        # with time zone - bug 9
+        element.text = "2012-01-31+06:00"
+        value = XMLDate().from_xml(element)
+        self.assertEqual(value, date(2012,01,31))
+        element.text = "2012-02-20-04:00"
+        value = XMLDate().from_xml(element)
+        self.assertEqual(value, date(2012,02,20))
+
     def test_integer(self):
         integer = XMLInteger(12)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.