summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/_strptime.py74
-rw-r--r--Lib/test/test_strptime.py70
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)