11# -*- coding:iso-8859-1 -*-
22"""
3- Copyright (c) 2003-2005 Gustavo Niemeyer <[email protected] > 3+ Copyright (c) 2003-2007 Gustavo Niemeyer <[email protected] > 44
55This module offers extensions to the standard python 2.3+
66datetime module.
77"""
88__author__ = "Gustavo Niemeyer <[email protected] >" 99__license__ = "PSF License"
1010
11- import os . path
11+ import datetime
1212import string
13- import sys
1413import time
14+ import sys
15+ import os
16+
17+ try :
18+ from cStringIO import StringIO
19+ except ImportError :
20+ from StringIO import StringIO
1521
16- import datetime
1722import relativedelta
1823import tz
1924
25+
2026__all__ = ["parse" , "parserinfo" ]
2127
28+
2229# Some pointers:
2330#
2431# http://www.cl.cam.ac.uk/~mgk25/iso-time.html
2835# http://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm
2936# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html
3037
31- try :
32- from cStringIO import StringIO
33- except ImportError :
34- from StringIO import StringIO
3538
36- class _timelex :
39+ class _timelex (object ):
40+
3741 def __init__ (self , instream ):
3842 if isinstance (instream , basestring ):
3943 instream = StringIO (instream )
@@ -139,6 +143,7 @@ def split(cls, s):
139143 return list (cls (s ))
140144 split = classmethod (split )
141145
146+
142147class _resultbase (object ):
143148
144149 def __init__ (self ):
@@ -156,7 +161,8 @@ def _repr(self, classname):
156161 def __repr__ (self ):
157162 return self ._repr (self .__class__ .__name__ )
158163
159- class parserinfo :
164+
165+ class parserinfo (object ):
160166
161167 # m from a.m/p.m, t from ISO T separator
162168 JUMP = [" " , "." , "," , ";" , "-" , "/" , "'" ,
@@ -204,7 +210,7 @@ def __init__(self, dayfirst=False, yearfirst=False):
204210 self .yearfirst = yearfirst
205211
206212 self ._year = time .localtime ().tm_year
207- self ._century = self ._year / 100 * 100
213+ self ._century = self ._year // 100 * 100
208214
209215 def _convert (self , lst ):
210216 dct = {}
@@ -281,15 +287,10 @@ def validate(self, res):
281287 return True
282288
283289
284- class parser :
290+ class parser ( object ) :
285291
286- def __init__ (self , info = parserinfo ):
287- if issubclass (info , parserinfo ):
288- self .info = parserinfo ()
289- elif isinstance (info , parserinfo ):
290- self .info = info
291- else :
292- raise TypeError , "Unsupported parserinfo type"
292+ def __init__ (self , info = None ):
293+ self .info = info or parserinfo ()
293294
294295 def parse (self , timestr , default = None ,
295296 ignoretz = False , tzinfos = None ,
@@ -360,9 +361,11 @@ def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False):
360361
361362 # Check if it's a number
362363 try :
363- value = float (l [i ])
364+ value_repr = l [i ]
365+ value = float (value_repr )
364366 except ValueError :
365367 value = None
368+
366369 if value is not None :
367370 # Token is a number
368371 len_li = len (l [i ])
@@ -386,10 +389,7 @@ def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False):
386389 # 19990101T235959[.59]
387390 res .hour = int (s [:2 ])
388391 res .minute = int (s [2 :4 ])
389- value = float (s [4 :])
390- res .second = int (value )
391- if value % 1 :
392- res .microsecond = int (1000000 * (value % 1 ))
392+ res .second , res .microsecond = _parsems (s [4 :])
393393 elif len_li == 8 :
394394 # YYYYMMDD
395395 s = l [i - 1 ]
@@ -423,15 +423,15 @@ def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False):
423423 if value % 1 :
424424 res .second = int (60 * (value % 1 ))
425425 elif idx == 2 :
426- res .second = int (value )
427- if value % 1 :
428- res .microsecond = int (1000000 * (value % 1 ))
426+ res .second , res .microsecond = \
427+ _parsems (value_repr )
429428 i += 1
430429 if i >= len_l or idx == 2 :
431430 break
432431 # 12h00
433432 try :
434- value = float (l [i ])
433+ value_repr = l [i ]
434+ value = float (value_repr )
435435 except ValueError :
436436 break
437437 else :
@@ -451,10 +451,7 @@ def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False):
451451 res .second = int (60 * (value % 1 ))
452452 i += 1
453453 if i < len_l and l [i ] == ':' :
454- value = float (l [i + 1 ])
455- res .second = int (value )
456- if value % 1 :
457- res .microsecond = int (1000000 * (value % 1 ))
454+ res .second , res .microsecond = _parsems (l [i + 1 ])
458455 i += 2
459456 elif i < len_l and l [i ] in ('-' , '/' , '.' ):
460457 sep = l [i ]
@@ -699,7 +696,8 @@ def parse(timestr, parserinfo=None, **kwargs):
699696 else :
700697 return DEFAULTPARSER .parse (timestr , ** kwargs )
701698
702- class _tzparser :
699+
700+ class _tzparser (object ):
703701
704702 class _result (_resultbase ):
705703
@@ -743,6 +741,8 @@ def parse(self, tzstr):
743741 if (i < len_l and
744742 (l [i ] in ('+' , '-' ) or l [i ][0 ] in "0123456789" )):
745743 if l [i ] in ('+' , '-' ):
744+ # Yes, that's right. See the TZ variable
745+ # documentation.
746746 signal = (1 ,- 1 )[l [i ] == '+' ]
747747 i += 1
748748 else :
@@ -865,11 +865,22 @@ def parse(self, tzstr):
865865
866866 except (IndexError , ValueError , AssertionError ):
867867 return None
868-
868+
869869 return res
870870
871+
871872DEFAULTTZPARSER = _tzparser ()
872873def _parsetz (tzstr ):
873874 return DEFAULTTZPARSER .parse (tzstr )
874875
876+
877+ def _parsems (value ):
878+ """Parse a I[.F] seconds value into (seconds, microseconds)."""
879+ if "." not in value :
880+ return int (value ), 0
881+ else :
882+ i , f = value .split ("." )
883+ return int (i ), int (f .ljust (6 , "0" )[:6 ])
884+
885+
875886# vim:ts=4:sw=4:et
0 commit comments