Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project!

## webware-checkins

 [Webware-checkins] r6426 - Webware/trunk/MiscUtils From: - 2007-04-07 01:59:47 ```Author: chrisz Date: Fri Apr 6 19:59:31 2007 New Revision: 6426 Modified: Webware/trunk/MiscUtils/BasicDateTime.py Log: Cleanup of BasicDateTime.py Modified: Webware/trunk/MiscUtils/BasicDateTime.py ============================================================================== --- Webware/trunk/MiscUtils/BasicDateTime.py (original) +++ Webware/trunk/MiscUtils/BasicDateTime.py Fri Apr 6 19:59:31 2007 @@ -33,10 +33,16 @@ MINYEAR = 1 MAXYEAR = 9999 + class DaysInMonth: - "Simple class to correctly calculate the days in a month in Python 2.2. The calendar.monthrange(year, month) fails in that version." + """Simple class to correctly calculate the days in a month in Python 2.2. + + The calendar.monthrange(year, month) fails in that version. + + """ def calculate(self, year, month): - return [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] + (month == 2 and self.isleap(year)) + return (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[month] \ + + (month == 2 and self.isleap(year)) def isleap(self, year): """Return 1 for leap years, 0 for non-leap years.""" @@ -44,10 +50,10 @@ def test(self): passed = 1 - for year in range (1,9999): - for month in range(1,12): - if DaysInMonth().calculate(year, month) <> calendar.monthrange(year, month)[1]: - print "Failed on %s-%s."%(year, month) + for year in range (1, 9999): + for month in range(1, 12): + if DaysInMonth().calculate(year, month) != calendar.monthrange(year, month)[1]: + print "Failed on %s-%s." % (year, month) passed = 0 if not passed: print "FAILED" @@ -56,22 +62,20 @@ return passed def weekday(self, year, month, day): - """Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12), - day (1-31).""" + """Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12), day (1-31).""" secs = mktime((year, month, day, 0, 0, 0, 0, 0, 0)) tuple = localtime(secs) return tuple[6] - - daysInMonth = DaysInMonth() + class datetime: - """ - DateTime(year,month=1,day=1,hour=0,minute=0,second=0.0) + """DateTime(year, month=1, day=1, hour=0, minute=0, second=0.0) Constructs a DateTime instance from the given values. - Assumes that the date is given in the Gregorian calendar (which it the one used in many countries today). + Assumes that the date is given in the Gregorian calendar + (which it the one used in many countries today). WARNING: Only very limited error checking is done for this class. The tuples are filled with the parameters from the last three numbers @@ -86,62 +90,69 @@ day 1-31 hour 0-23 minute 0-59 - second 0-59 Apparantly it is possible to have a double leap second in python + second 0-59 Apparantly it is possible to have a double leap second in Python. However, to maintain compatibility with databases, this isn't allowed. WARNING: Seconds are rounded to two decimal places. + """ - def __init__(self,year,month,day,hour=0,minute=0,second=0,microsecond=0): - """Either set one of the sets options: - year, month, day, hour, minute, second - Each integers except second which can be a float. - # XXX possible problems with months with more days in than they actually have. + def __init__(self, year, month, day, hour=0, minute=0, second=0, microsecond=0): + """Initialize datetime object. + + All arguments are integers except second which can be a float. + + WARNING: Possible problems with months with more days in than they actually have. + """ - dates = ['year','month','day','hour','minute'] + dates = ('year', 'month', 'day', 'hour', 'minute') counter = 0 - for item in [year,month,day,hour,minute]: - if type(item) not in [type(1), type(1L)]: - raise TypeError("The variable '%s' should be an integer."%dates[counter]) + for item in (year, month, day, hour, minute): + if type(item) not in (type(1), type(1L)): + raise TypeError("The variable '%s' should be an integer." + % dates[counter]) counter += 1 - if type(second) not in [type(1), type(1L)]:# and type(second) <> type(1.004): - raise ValueError("The variable 'second' should be an Integer or a Long.")# or a float.") + if type(second) not in (type(1), type(1L)): # and type(second) != type(1.1) + raise ValueError("The variable 'second' should be an Integer or a Long.") # or a float # Very basic error checking and initialisation. - if year < MINYEAR or year > MAXYEAR: - raise ValueError('The year value must be between %s and %s inclusive.'%(MINYEAR, MAXYEAR)) + if not MINYEAR <= year <= MAXYEAR: + raise ValueError('The year value must be between %s and %s inclusive.' + % (MINYEAR, MAXYEAR)) else: self.year = year - if month < 1 or month > 12: + if not 1 <= month < 1 <= 12: raise ValueError('The month value must be between 1 and 12 inclusive.') else: self.month = month - if day < 1 or day > daysInMonth.calculate(year, month): - raise ValueError('The day value must be between 1 and %s inclusive.'%daysInMonth.calculate(year, month)) + if not 1 <= day <= daysInMonth.calculate(year, month): + raise ValueError('The day value must be between 1 and %s inclusive.' + % daysInMonth.calculate(year, month)) else: self.day = day - if hour < 0 or hour > 23: + if not 0 <= hour < 24: raise ValueError('The hour value must be between 0 and 23 inclusive.') else: self.hour = hour - if minute < 0 or minute > 59: + if not 0 <= minute < 60: raise ValueError('The minutes value must be between 0 and 59 inclusive.') else: self.minute = minute - if second < 0 or second > 59: + if not 0 <= second < 60: raise ValueError('The seconds value must be between 0 and 59 inclusive.') else: self.second = second - if microsecond < 0 or microsecond > 1000000: - raise ValueError('The microseconds value must be between 0 and 1000000 inclusive.') + if not microsecond 0 <= microsecond < 1000000: + raise ValueError('The microseconds value must be between 0 and 999999 inclusive.') else: self.microsecond = microsecond def now(self): - "Return the current date and time as a datetime." + """Return the current date and time as a datetime.""" now = t.localtime() - return datetime(now[0],now[1],now[2],now[3],now[4],now[5]) + return datetime(now[0], now[1], now[2], now[3], now[4], now[5]) ## Comparison Operators ## @@ -240,15 +251,16 @@ return 1 def __str__(self): - "Return the object as standard SQL." + """Return the object as standard SQL.""" return self.isoformat() def __repr__(self): - "Return a string representation of the object." - return "datetime.datetime(%s,%s,%s,%s,%s,%s)"%(self.year, self.month, self.day, self.hour, self.minute, self.second) + """Return a string representation of the object.""" + return "datetime.datetime(%s, %s, %s, %s, %s, %s)" % ( + self.year, self.month, self.day, self.hour, self.minute, self.second) def __getitem__(self, item): - "Enable dictionary-style attribute reading for year, month, day, hour, minute and second." + """Enable dictionary-style attribute reading for year, month, day, hour, minute and second.""" if item == 'year': return self.year elif item == 'month': @@ -262,25 +274,29 @@ elif item == 'second': return self.second else: - raise KeyError("'%s' is not a valid attribute for a Date class."%item) + raise KeyError("'%s' is not a valid attribute for a Date class." % item) ## Formatting ## - def _addZeros(self,num,s): - "Private function to add an appropriate number of zeros to s such that len(s) is num." + def _addZeros(self, num, s): + """Private function to add an appropriate number of zeros to s such that len(s) is num.""" s = str(s) - while( len(s) < num ): - s = '0'+s + while (len(s) < num): + s = '0' + s return s def _isodate(self): - "Return the date as a standard SQL string of the format 'YYYY-MM-DD'." - return str(self._addZeros(4,self.year))+"-"+str(self._addZeros(2,self.month))+"-"+str(self._addZeros(2,self.day)) + """Return the date as a standard SQL string of the format 'YYYY-MM-DD'.""" + return (str(self._addZeros(4, self.year)) + + "-" + str(self._addZeros(2, self.month)) + + "-" + str(self._addZeros(2, self.day))) def _isotime(self): - "Return the time as a standard SQL string in the format 'HH:MM::SS.ss'." - return str(self._addZeros(2,self.hour))+":"+str(self._addZeros(2,self.minute))+":"+str(self._addZeros(2,self.second))#str(self._addZeros(2,int(self.second)))+'.'+s + """Return the time as a standard SQL string in the format 'HH:MM::SS.ss'.""" + return (str(self._addZeros(2, self.hour)) + + ":" + str(self._addZeros(2, self.minute)) + + ":" + str(self._addZeros(2, self.second))) def strftime(self, format): """Format the time using standard time module string format strings. @@ -290,139 +306,161 @@ %b Locale's abbreviated month name. %B Locale's full month name. %c Locale's appropriate date and time representation. - %d Day of the month as a decimal number [01,31]. - %H Hour (24-hour clock) as a decimal number [00,23]. - %I Hour (12-hour clock) as a decimal number [01,12]. - %j Day of the year as a decimal number [001,366]. - %m Month as a decimal number [01,12]. - %M Minute as a decimal number [00,59]. + %d Day of the month as a decimal number [01, 31]. + %H Hour (24-hour clock) as a decimal number [00, 23]. + %I Hour (12-hour clock) as a decimal number [01, 12]. + %j Day of the year as a decimal number [001, 366]. + %m Month as a decimal number [01, 12]. + %M Minute as a decimal number [00, 59]. %p Locale's equivalent of either AM or PM. - %S Second as a decimal number [00,61]. (1) - %U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. - %w Weekday as a decimal number [0(Sunday),6]. - %W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. + %S Second as a decimal number [00, 61]. (1) + %U Week number of the year (Sunday as the first day of the week) + as a decimal number [00, 53]. All days in a new year preceding + the first Sunday are considered to be in week 0. + %w Weekday as a decimal number [0(Sunday), 6]. + %W Week number of the year (Monday as the first day of the week) + as a decimal number [00, 53]. All days in a new year preceding + the first Monday are considered to be in week 0. %x Locale's appropriate date representation. %X Locale's appropriate time representation. - %y Year without century as a decimal number [00,99]. + %y Year without century as a decimal number [00, 99]. %Y Year with century as a decimal number. %Z Time zone name (no characters if no time zone exists). %% A literal "%" character. """ - #raise Exception(self.timetuple()) return t.strftime(format, self.timetuple()) ## Conversion ## def timetuple(self): - """Returns the date and time as a python tuple as constructed by time.localtime(). - WARNING: The last 3 entries in the tuple are obtained from time.localtime() and do not represent anything.""" + """Return the date and time as a python tuple as constructed by time.localtime(). + + WARNING: The last 3 entries in the tuple are obtained from time.localtime() + and do not represent anything. + + """ sql = self.isoformat() - wday = calendar.weekday(int(sql[0:4]),int(sql[5:7]),int(sql[8:10])) - return (int(sql[0:4]),int(sql[5:7]),int(sql[8:10]),int(sql[11:13]),int(sql[14:16]),int(sql[17:19]),wday,0,-1)#,0,0,-1) ,0,0,-1) + wday = calendar.weekday(int(sql[0:4]), int(sql[5:7]), int(sql[8:10])) + return (int(sql[0:4]), int(sql[5:7]), int(sql[8:10]), int(sql[11:13]), + int(sql[14:16]), int(sql[17:19]), wday, 0, -1) def isoformat(self): - "Return the date and time as a standard SQL string of the format 'YYYY-MM-DD HH:MM:SS.ss'." + """Return the date and time as a standard SQL string of the format 'YYYY-MM-DD HH:MM:SS.ss'.""" return self._isodate() + ' ' + self._isotime() class date(datetime): """Constructs an object holding a date value. + Is just another name binding for DateTime(). - The time part is set to '00:00:00.00'.""" + The time part is set to '00:00:00.00'. - def __init__(self,year,month,day): + """ - dates = ['year','month','day'] + def __init__(self, year, month, day): + + dates = ('year', 'month', 'day') counter = 0 - for item in [year,month,day]: - if type(item) not in [ type(1), type(1L)]: - raise TypeError("The variable '%s' should be an Integer or a Long."%dates[counter]) + for item in (year, month, day): + if type(item) not in (type(1), type(1L)): + raise TypeError("The variable '%s' should be an Integer or a Long." + % dates[counter]) counter += 1 - # Very basic error checking and initialisation. - if year < MINYEAR or year > MAXYEAR: - raise ValueError('The year value must be between %s and %s inclusive.'%(MINYEAR, MAXYEAR)) + if not MINYEAR <= year <= MAXYEAR: + raise ValueError('The year value must be between %s and %s inclusive.' + % (MINYEAR, MAXYEAR)) else: self.year = year - if month < 1 or month > 12: + if not 1 <= month < 12: raise ValueError('The month value must be between 1 and 12 inclusive.') else: self.month = month - if day < 1 or day > daysInMonth.calculate(year, month): - raise ValueError('The day value must be between 1 and %s inclusive.'%daysInMonth.calculate(year, month)) + if not 1 <= day <= daysInMonth.calculate(year, month): + raise ValueError('The day value must be between 1 and %s inclusive.' + % daysInMonth.calculate(year, month)) else: self.day = day def __repr__(self): - "Return a string representation of the object." - return "datetime.date(%s,%s,%s)"%(self.year,self.month, self.day) + """Return a string representation of the object.""" + return "datetime.date(%s, %s, %s)" % (self.year, self.month, self.day) def isoformat(self): - "Return the date as a standard SQL string of the format 'YYYY-MM-DD'." + """Return the date as a standard SQL string of the format 'YYYY-MM-DD'.""" return self._isodate() def timetuple(self): """Returns the date as a python tuple as constructed by time.localtime(). - WARNING: The last 6 entries in the tuple are obtained from time.localtime() and do not represent anything.""" + + WARNING: The last 6 entries in the tuple are obtained from time.localtime() + and do not represent anything. + + """ sql = self.isoformat() - wday = calendar.weekday(int(sql[0:4]),int(sql[5:7]),int(sql[8:10])) - return (int(sql[0:4]),int(sql[5:7]),int(sql[8:10]),0,0,0,wday,0,-1) + wday = calendar.weekday(int(sql[0:4]), int(sql[5:7]), int(sql[8:10])) + return (int(sql[0:4]), int(sql[5:7]), int(sql[8:10]), 0, 0, 0, wday, 0, -1) def now(self): - "Return the current date and time as a datetime." + """Return the current date and time as a datetime.""" now = t.localtime() - return date(now[0],now[1],now[2]) + return date(now[0], now[1], now[2]) + class time(datetime): - """Constructs an object holding a time value. + """Construct an object holding a time value. + Is just another name binding for DateTime(). - The date part is set to '2000-01-01'.""" + The date part is set to '2000-01-01'. + + """ - def __init__(self,hour=0,minute=0,second=0,microsecond=0): + def __init__(self, hour=0, minute=0, second=0, microsecond=0): - dates = ['hour','minute'] + dates = ('hour', 'minute') counter = 0 - for item in [hour,minute]: - if type(item) not in [type(1), type(1L)]: - raise TypeError("The variable '%s' should be an Integer or a Long."%dates[counter]) + for item in (hour, minute): + if type(item) not in (type(1), type(1L)): + raise TypeError("The variable '%s' should be an Integer or a Long." + % dates[counter]) counter += 1 - if type(second) <> type(1):# and type(second) <> type(1.004): - raise ValueError("The variable 'second' should be an integer.")# or a float.") + if type(second) != type(1): # and type(second) != type(1.1): + raise ValueError("The variable 'second' should be an integer.") # or a float # Very basic error checking and initialisation. - if hour < 0 or hour > 23: + if not 0 <= hour < 24: raise ValueError('The hour value must be between 0 and 23 inclusive.') else: self.hour = hour - if minute < 0 or minute > 59: + if not 0 <= minute < 60: raise ValueError('The minutes value must be between 0 and 59 inclusive.') else: self.minute = minute - if second < 0 or second > 59: + if not 0 <= second < 60: raise ValueError('The seconds value must be between 0 and 59 inclusive.') else: self.second = second - if microsecond < 0 or microsecond > 1000000: - raise ValueError('The microseconds value must be between 0 and 1000000 inclusive.') + if not 0 <= microsecond < 1000000: + raise ValueError('The microseconds value must be between 0 and 999999 inclusive.') else: self.microsecond = microsecond def __repr__(self): - "Return a string representation of the object." - return "datetime.time(%s,%s,%s)"%(self.hour, self.minute, self.second) + """Return a string representation of the object.""" + return "datetime.time(%s, %s, %s)" % (self.hour, self.minute, self.second) def isoformat(self): - "Return the time as a standard SQL string in the format 'HH:MM::SS.ss'." + """Return the time as a standard SQL string in the format 'HH:MM::SS.ss'.""" return self._isotime() def timetuple(self): raise AttributeError('time objects do not have a timetuple method.') def now(self): - "Return the current date and time as a datetime." + """Return the current date and time as a datetime.""" now = t.localtime() - return time(now[3],now[4],now[5]) + return time(now[3], now[4], now[5]) ```