diff options
-rw-r--r-- | Lib/_strptime.py | 74 | ||||
-rw-r--r-- | Lib/test/test_strptime.py | 70 |
2 files changed, 56 insertions, 88 deletions
diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 4afc8fc..55391c1 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -6,32 +6,25 @@ CLASSES: time information as is returned by time.strftime() FUNCTIONS: - firstjulian -- Calculates the Julian date up to the first of the specified - year - gregorian -- Calculates the Gregorian date based on the Julian day and - year - julianday -- Calculates the Julian day since the first of the year based - on the Gregorian date - dayofweek -- Calculates the day of the week from the Gregorian date. + _getlang -- Figure out what language is being used for the locale strptime -- Calculates the time struct represented by the passed-in string -Requires Python 2.2.1 or higher. +Requires Python 2.2.1 or higher (mainly because of the use of property()). Can be used in Python 2.2 if the following line is added: - >>> True = 1; False = 0 + True = 1; False = 0 """ import time import locale import calendar from re import compile as re_compile from re import IGNORECASE +from datetime import date as datetime_date __author__ = "Brett Cannon" -__email__ = "drifty@bigfoot.com" +__email__ = "brett@python.org" __all__ = ['strptime'] -RegexpType = type(re_compile('')) - def _getlang(): # Figure out what the current language is set to. current_lang = locale.getlocale(locale.LC_TIME)[0] @@ -425,7 +418,7 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): month = day = 1 hour = minute = second = 0 tz = -1 - # Defaulted to -1 so as to signal using functions to calc values + # weekday and julian defaulted to -1 so as to signal need to calculate values weekday = julian = -1 found_dict = found.groupdict() for group_key in found_dict.iterkeys(): @@ -495,16 +488,21 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): tz = 1 elif locale_time.timezone[2].lower() == found_zone: tz = -1 - #XXX <bc>: If calculating fxns are never exposed to the general - #populous then just inline calculations. Also might be able to use - #``datetime`` and the methods it provides. + # Cannot pre-calculate datetime_date() since can change in Julian + #calculation and thus could have different value for the day of the week + #calculation if julian == -1: - julian = julianday(year, month, day) - else: # Assuming that if they bothered to include Julian day it will + # Need to add 1 to result since first day of the year is 1, not 0. + julian = datetime_date(year, month, day).toordinal() - \ + datetime_date(year, 1, 1).toordinal() + 1 + else: # Assume that if they bothered to include Julian day it will #be accurate - year, month, day = gregorian(julian, year) + datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal()) + year = datetime_result.year + month = datetime_result.month + day = datetime_result.day if weekday == -1: - weekday = dayofweek(year, month, day) + weekday = datetime_date(year, month, day).weekday() return time.struct_time((year, month, day, hour, minute, second, weekday, julian, tz)) @@ -522,39 +520,3 @@ def _insensitiveindex(lst, findme): else: raise ValueError("value not in list") -def firstjulian(year): - """Calculate the Julian date up until the first of the year.""" - return ((146097 * (year + 4799)) // 400) - 31738 - -def julianday(year, month, day): - """Calculate the Julian day since the beginning of the year. - Calculated from the Gregorian date. - """ - a = (14 - month) // 12 - return (day - 32045 - + (((153 * (month + (12 * a) - 3)) + 2) // 5) - + ((146097 * (year + 4800 - a)) // 400)) - firstjulian(year) + 1 - -def gregorian(julian, year): - """Return 3-item list containing Gregorian date based on the Julian day.""" - a = 32043 + julian + firstjulian(year) - b = ((4 * a) + 3) // 146097 - c = a - ((146097 * b) // 4) - d = ((4 * c) + 3) // 1461 - e = c - ((1461 * d) // 4) - m = ((5 * e) + 2) // 153 - day = 1 + e - (((153 * m) + 2) // 5) - month = m + 3 - (12 * (m // 10)) - year = (100 * b) + d - 4800 + (m // 10) - return [year, month, day] - -def dayofweek(year, month, day): - """Calculate the day of the week (Monday is 0).""" - a = (14 - month) // 12 - y = year - a - weekday = (day + y + ((97 * y) // 400) - + ((31 * (month + (12 * a) -2 )) // 12)) % 7 - if weekday == 0: - return 6 - else: - return weekday-1 diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 2510a90..e708f4c 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -329,37 +329,6 @@ class StrptimeTests(unittest.TestCase): "Default values for strptime() are incorrect;" " %s != %s" % (strp_output, defaults)) -class FxnTests(unittest.TestCase): - """Test functions that fill in info by validating result and are triggered - properly.""" - - def setUp(self): - """Create an initial time tuple.""" - self.time_tuple = time.gmtime() - - def test_julianday_result(self): - # Test julianday - result = _strptime.julianday(self.time_tuple[0], self.time_tuple[1], - self.time_tuple[2]) - self.failUnless(result == self.time_tuple[7], - "julianday failed; %s != %s" % - (result, self.time_tuple[7])) - - def test_gregorian_result(self): - # Test gregorian - result = _strptime.gregorian(self.time_tuple[7], self.time_tuple[0]) - comparison = [self.time_tuple[0], self.time_tuple[1], self.time_tuple[2]] - self.failUnless(result == comparison, - "gregorian() failed; %s != %s" % (result, comparison)) - - def test_dayofweek_result(self): - # Test dayofweek - result = _strptime.dayofweek(self.time_tuple[0], self.time_tuple[1], - self.time_tuple[2]) - comparison = self.time_tuple[6] - self.failUnless(result == comparison, - "dayofweek() failed; %s != %s" % (result, comparison)) - class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" @@ -380,15 +349,52 @@ class JulianTests(unittest.TestCase): # use 2004, since it is a leap year, we have 366 days eq(_strptime.strptime('%d 2004' % i, '%j %Y')[7], i) +class CalculationTests(unittest.TestCase): + """Test that strptime() fills in missing info correctly""" + + def setUp(self): + self.time_tuple = time.gmtime() + + def test_julian_calculation(self): + # Make sure that when Julian is missing that it is calculated + format_string = "%Y %m %d %H %M %S %w %Z" + result = _strptime.strptime(time.strftime(format_string, self.time_tuple), + format_string) + self.failUnless(result.tm_yday == self.time_tuple.tm_yday, + "Calculation of tm_yday failed; %s != %s" % + (result.tm_yday, self.time_tuple.tm_yday)) + + def test_gregorian_calculation(self): + # Test that Gregorian date can be calculated from Julian day + format_string = "%Y %H %M %S %w %j %Z" + result = _strptime.strptime(time.strftime(format_string, self.time_tuple), + format_string) + self.failUnless(result.tm_year == self.time_tuple.tm_year and + result.tm_mon == self.time_tuple.tm_mon and + result.tm_mday == self.time_tuple.tm_mday, + "Calculation of Gregorian date failed;" + "%s-%s-%s != %s-%s-%s" % + (result.tm_year, result.tm_mon, result.tm_mday, + self.time_tuple.tm_year, self.time_tuple.tm_mon, + self.time_tuple.tm_mday)) + + def test_day_of_week_calculation(self): + # Test that the day of the week is calculated as needed + format_string = "%Y %m %d %H %S %j %Z" + result = _strptime.strptime(time.strftime(format_string, self.time_tuple), + format_string) + self.failUnless(result.tm_wday == self.time_tuple.tm_wday, + "Calculation of day of the week failed;" + "%s != %s" % (result.tm_wday, self.time_tuple.tm_wday)) def test_main(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(LocaleTime_Tests)) suite.addTest(unittest.makeSuite(TimeRETests)) suite.addTest(unittest.makeSuite(StrptimeTests)) - suite.addTest(unittest.makeSuite(FxnTests)) suite.addTest(unittest.makeSuite(Strptime12AMPMTests)) suite.addTest(unittest.makeSuite(JulianTests)) + suite.addTest(unittest.makeSuite(CalculationTests)) test_support.run_suite(suite) |