Kirill Simonov avatar Kirill Simonov committed eb81eab

Fix loss of microsecond precision in datetime.datetime constructor (fix #30).
Thanks to edemaine@mit.edu for the bug report and the patch.

Comments (0)

Files changed (5)

lib/yaml/constructor.py

                 (?P<hour>[0-9][0-9]?)
                 :(?P<minute>[0-9][0-9])
                 :(?P<second>[0-9][0-9])
-                (?:(?P<fraction>\.[0-9]*))?
+                (?:\.(?P<fraction>[0-9]*))?
                 (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
                 (?::(?P<tz_minute>[0-9][0-9]))?))?)?$''', re.X)
 
         second = int(values['second'])
         fraction = 0
         if values['fraction']:
-            fraction = int(float(values['fraction'])*1000000)
+            fraction = int(values['fraction'][:6].ljust(6, '0'))
         delta = None
         if values['tz_sign']:
             tz_hour = int(values['tz_hour'])

tests/data/timestamp-bugs.code

     datetime.datetime(2001, 12, 14, 21, 59, 43, 1010),
     datetime.datetime(2001, 12, 14, 21, 59, 43, 0, FixedOffset(60, "+1")),
     datetime.datetime(2001, 12, 14, 21, 59, 43, 0, FixedOffset(-90, "-1:30")),
+    datetime.datetime(2005, 7, 8, 17, 35, 4, 517600),
 ]

tests/data/timestamp-bugs.data

 - 2001-12-14 21:59:43.00101
 - 2001-12-14 21:59:43+1
 - 2001-12-14 21:59:43-1:30
+- 2005-07-08 17:35:04.517600

tests/test_constructor.py

                         if (item1 != item1 or (item1 == 0.0 and item1 == 1.0)) and  \
                                 (item2 != item2 or (item2 == 0.0 and item2 == 1.0)):
                             continue
+                        if isinstance(item1, datetime.datetime) \
+                                and isinstance(item2, datetime.datetime):
+                            self.failUnlessEqual(item1.microsecond,
+                                    item2.microsecond)
                         if isinstance(item1, datetime.datetime):
                             item1 = item1.utctimetuple()
                         if isinstance(item2, datetime.datetime):

tests/test_representer.py

                         if (item1 != item1 or (item1 == 0.0 and item1 == 1.0)) and  \
                                 (item2 != item2 or (item2 == 0.0 and item2 == 1.0)):
                             continue
+                        if isinstance(item1, datetime.datetime) \
+                                and isinstance(item2, datetime.datetime):
+                            self.failUnlessEqual(item1.microsecond,
+                                    item2.microsecond)
                         if isinstance(item1, datetime.datetime):
                             item1 = item1.utctimetuple()
                         if isinstance(item2, datetime.datetime):
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.