def test_TimeRE_recreation(self): # The TimeRE instance should be recreated upon changing the locale. locale_info = locale.getlocale(locale.LC_TIME) try: locale.setlocale(locale.LC_TIME, ('en_US', 'UTF8')) except locale.Error: return try: _strptime.strptime('10', '%d') # Get the current cache object. first_time_re = _strptime._TimeRE_cache try: # Change the locale and force a recreation of the cache. locale.setlocale(locale.LC_TIME, ('de_DE', 'UTF8')) _strptime.strptime('10', '%d') # Get the new cache object. second_time_re = _strptime._TimeRE_cache # They should not be identical. self.assert_(first_time_re is not second_time_re) # Possible test locale is not supported while initial locale is. # If this is the case just suppress the exception and fall-through # to the reseting to the original locale. except locale.Error: pass # Make sure we don't trample on the locale setting once we leave the # test. finally: locale.setlocale(locale.LC_TIME, locale_info)
def test_timezone(self): # Test timezone directives. # When gmtime() is used with %Z, entire result of strftime() is empty. # Check for equal timezone names deals with bad locale info when this # occurs; first found in FreeBSD 4.4. strp_output = _strptime.strptime("UTC", "%Z") self.failUnlessEqual(strp_output.tm_isdst, 0) strp_output = _strptime.strptime("GMT", "%Z") self.failUnlessEqual(strp_output.tm_isdst, 0) if sys.platform == "mac": # Timezones don't really work on MacOS9 return time_tuple = time.localtime() strf_output = time.strftime("%Z") #UTC does not have a timezone strp_output = _strptime.strptime(strf_output, "%Z") locale_time = _strptime.LocaleTime() if time.tzname[0] != time.tzname[1] or not time.daylight: self.failUnless( strp_output[8] == time_tuple[8], "timezone check failed; '%s' -> %s != %s" % (strf_output, strp_output[8], time_tuple[8])) else: self.failUnless( strp_output[8] == -1, "LocaleTime().timezone has duplicate values and " "time.daylight but timezone value not set to -1")
def timestr2secs_utc(timestr): """ Convert a timestring to UTC (=GMT) seconds. The format is either one of these two: '20020702100000 CDT' '200209080000 +0100' """ # Accounting for feeds that pre-adjust start/finish timestamps in the feed to the # correct timezone and DO NOT provide a timestamp offset (as it would be zero). # An example of this strange behaviour is the OzTivo feed if config.XMLTV_TIMEZONE is not None: tval = timestr tz = config.XMLTV_TIMEZONE else: # This is either something like 'EDT', or '+1' try: tval, tz = timestr.split() except ValueError: tval = timestr tz = str(-time.timezone / 3600) if tz == 'CET': tz = '+1' # Is it the '+1' format? if tz[0] == '+' or tz[0] == '-': tmTuple = (int(tval[0:4]), int(tval[4:6]), int(tval[6:8]), int(tval[8:10]), int(tval[10:12]), 0, -1, -1, -1) secs = calendar.timegm(tmTuple) adj_neg = int(tz) >= 0 try: min = int(tz[3:5]) except ValueError: # sometimes the mins are missing :-( min = 0 adj_secs = int(tz[1:3]) * 3600 + min * 60 if adj_neg: secs -= adj_secs else: secs += adj_secs else: # No, use the regular conversion ## WARNING! BUG HERE! # The line below is incorrect; the strptime.strptime function doesn't # handle time zones. There is no obvious function that does. Therefore # this bug is left in for someone else to solve. try: secs = time.mktime(strptime.strptime(timestr, xmltv.date_format)) except ValueError: timestr = timestr.replace('EST', '') secs = time.mktime(strptime.strptime(timestr, xmltv.date_format)) return secs
def test_new_localetime(self): # A new LocaleTime instance should be created when a new TimeRE object # is created. locale_time_id = id(_strptime._TimeRE_cache.locale_time) _strptime._TimeRE_cache.locale_time.lang = "Ni" _strptime.strptime("10", "%d") self.failIfEqual(locale_time_id, id(_strptime._TimeRE_cache.locale_time))
def DateFromString(value): """Return the time value from the string. A short date format (without the time) is supported in addition to the long date format.""" try: date = _strptime.strptime(value, SHORT_DATE_FORMAT) except ValueError: date = _strptime.strptime(value, LONG_DATE_FORMAT) return time.mktime(date)
def test_new_localetime(self): # A new LocaleTime instance should be created when a new TimeRE object # is created. original_locale_time = _strptime._TimeRE_cache.locale_time _strptime._TimeRE_cache.locale_time.lang = "Ni" _strptime.strptime("10", "%d") self.assert_(original_locale_time is not _strptime._TimeRE_cache.locale_time)
def test_time_re_recreation(self): # Make sure cache is recreated when current locale does not match what # cached object was created with. _strptime.strptime("10", "%d") _strptime._locale_cache.locale_time = _strptime.LocaleTime(lang="Ni") original_time_re = id(_strptime._locale_cache) _strptime.strptime("10", "%d") self.failIfEqual(original_time_re, id(_strptime._locale_cache))
def test_time_re_recreation(self): # Make sure cache is recreated when current locale does not match what # cached object was created with. _strptime.strptime("10", "%d") _strptime._TimeRE_cache.locale_time.lang = "Ni" original_time_re = id(_strptime._TimeRE_cache) _strptime.strptime("10", "%d") self.failIfEqual(original_time_re, id(_strptime._TimeRE_cache))
def test_caseinsensitive(self): # Should handle names case-insensitively. strf_output = time.strftime("%B", self.time_tuple) self.failUnless(_strptime.strptime(strf_output.upper(), "%B"), "strptime does not handle ALL-CAPS names properly") self.failUnless(_strptime.strptime(strf_output.lower(), "%B"), "strptime does not handle lowercase names properly") self.failUnless(_strptime.strptime(strf_output.capitalize(), "%B"), "strptime does not handle capword names properly")
def test_regex_cleanup(self): # Make sure cached regexes are discarded when cache becomes "full". try: del _strptime._regex_cache['%d'] except KeyError: pass bogus_key = 0 while len(_strptime._regex_cache) <= _strptime._CACHE_MAX_SIZE: _strptime._regex_cache[bogus_key] = None bogus_key += 1 _strptime.strptime("10", "%d") self.failUnlessEqual(len(_strptime._regex_cache), 1)
def test_ValueError(self): # Make sure ValueError is raised when match fails or format is bad self.assertRaises(ValueError, _strptime.strptime, data_string="%d", format="%A") for bad_format in ("%", "% ", "%e"): try: _strptime.strptime("2005", bad_format) except ValueError: continue except Exception, err: self.fail("'%s' raised %s, not ValueError" % (bad_format, err.__class__.__name__)) else: self.fail("'%s' did not raise ValueError" % bad_format)
def test_percent(self): # Make sure % signs are handled properly strf_output = time.strftime("%m %% %Y", self.time_tuple) strp_output = _strptime.strptime(strf_output, "%m %% %Y") self.failUnless(strp_output[0] == self.time_tuple[0] and strp_output[1] == self.time_tuple[1], "handling of percent sign failed")
def test_defaults(self): # Default return value should be (1900, 1, 1, 0, 0, 0, 0, 1, 0) defaults = (1900, 1, 1, 0, 0, 0, 0, 1, -1) strp_output = _strptime.strptime('1', '%m') self.failUnless(strp_output == defaults, "Default values for strptime() are incorrect;" " %s != %s" % (strp_output, defaults))
def helper(self, directive, position): """Helper fxn in testing.""" strf_output = time.strftime("%" + directive, self.time_tuple) strp_output = _strptime.strptime(strf_output, "%" + directive) self.failUnless(strp_output[position] == self.time_tuple[position], "testing of '%s' directive failed; '%s' -> %s != %s" % (directive, strf_output, strp_output[position], self.time_tuple[position]))
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_hour(self): # Test hour directives self.helper('H', 3) strf_output = time.strftime("%I %p", self.time_tuple) strp_output = _strptime.strptime(strf_output, "%I %p") self.failUnless(strp_output[3] == self.time_tuple[3], "testing of '%%I %%p' directive failed; '%s' -> %s != %s" % (strf_output, strp_output[3], self.time_tuple[3]))
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_escaping(self): # Make sure all characters that have regex significance are escaped. # Parentheses are in a purposeful order; will cause an error of # unbalanced parentheses when the regex is compiled if they are not # escaped. # Test instigated by bug #796149 . need_escaping = ".^$*+?{}\[]|)(" self.failUnless(_strptime.strptime(need_escaping, need_escaping))
def strptime(string, format="%a %b %d %H:%M:%S %Y"): """strptime(string, format) -> struct_time Parse a string to a time tuple according to a format specification. See the library reference manual for formatting codes (same as strftime()).""" import _strptime # from the CPython standard library return _strptime.strptime(string, format)
def test_helper(ymd_tuple, test_reason): for directive in ('W', 'U'): format_string = "%%Y %%%s %%w" % directive dt_date = datetime_date(*ymd_tuple) strp_input = dt_date.strftime(format_string) strp_output = _strptime.strptime(strp_input, format_string) self.failUnless( strp_output[:3] == ymd_tuple, "%s(%s) test failed w/ '%s': %s != %s (%s != %s)" % (test_reason, directive, strp_input, strp_output[:3], ymd_tuple, strp_output[7], dt_date.timetuple()[7]))
def test_helper(ymd_tuple, test_reason): for directive in ('W', 'U'): format_string = "%%Y %%%s %%w" % directive dt_date = datetime_date(*ymd_tuple) strp_input = dt_date.strftime(format_string) strp_output = _strptime.strptime(strp_input, format_string) self.failUnless(strp_output[:3] == ymd_tuple, "%s(%s) test failed w/ '%s': %s != %s (%s != %s)" % (test_reason, directive, strp_input, strp_output[:3], ymd_tuple, strp_output[7], dt_date.timetuple()[7]))
def test_year(self): # Test that the year is handled properly for directive in ('y', 'Y'): self.helper(directive, 0) # Must also make sure %y values are correct for bounds set by Open Group for century, bounds in ((1900, ('69', '99')), (2000, ('00', '68'))): for bound in bounds: strp_output = _strptime.strptime(bound, '%y') expected_result = century + int(bound) self.failUnless(strp_output[0] == expected_result, "'y' test failed; passed in '%s' " "and returned '%s'" % (bound, strp_output[0]))
def test_timezone(self): # Test timezone directives. # When gmtime() is used with %Z, entire result of strftime() is empty. # Check for equal timezone names deals with bad locale info when this # occurs; first found in FreeBSD 4.4. strp_output = _strptime.strptime("UTC", "%Z") self.failUnlessEqual(strp_output.tm_isdst, 0) strp_output = _strptime.strptime("GMT", "%Z") self.failUnlessEqual(strp_output.tm_isdst, 0) time_tuple = time.localtime() strf_output = time.strftime("%Z") #UTC does not have a timezone strp_output = _strptime.strptime(strf_output, "%Z") locale_time = _strptime.LocaleTime() if time.tzname[0] != time.tzname[1] or not time.daylight: self.failUnless(strp_output[8] == time_tuple[8], "timezone check failed; '%s' -> %s != %s" % (strf_output, strp_output[8], time_tuple[8])) else: self.failUnless(strp_output[8] == -1, "LocaleTime().timezone has duplicate values and " "time.daylight but timezone value not set to -1")
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_time_re_recreation(self): # Make sure cache is recreated when current locale does not match what # cached object was created with. _strptime.strptime("10", "%d") _strptime.strptime("2005", "%Y") _strptime._TimeRE_cache.locale_time.lang = "Ni" original_time_re = _strptime._TimeRE_cache _strptime.strptime("10", "%d") self.assert_(original_time_re is not _strptime._TimeRE_cache) self.failUnlessEqual(len(_strptime._regex_cache), 1)
def test_time_re_recreation(self): # Make sure cache is recreated when current locale does not match what # cached object was created with. _strptime.strptime("10", "%d") _strptime.strptime("2005", "%Y") _strptime._TimeRE_cache.locale_time.lang = "Ni" original_time_re = id(_strptime._TimeRE_cache) _strptime.strptime("10", "%d") self.failIfEqual(original_time_re, id(_strptime._TimeRE_cache)) self.failUnlessEqual(len(_strptime._regex_cache), 1)
def __init__(self, *args, **kwargs): if len(args) == 1: if type(args[0]) not in (str, unicode): raise TypeError("arg[0] must be a date string") self.__initProperties__() fmt = kwargs.get('format') if fmt is None: fmt = "%d/%m/%Y" # apologies to any North American's st = strptime(args[0], fmt) if _version == 27: st = st[0] self._y, self._m, self._d, self._hh, self._mm, self._ss, self._us = st.tm_year, st.tm_mon, st.tm_mday, st.tm_hour, st.tm_min, st.tm_sec, 0 return None elif len(args) > 1: raise TypeError("len(args) > 1") elif len(kwargs) == 0: raise TypeError("Must initialise with either *args or **kwargs") elif len(kwargs) > 0: self.__initProperties__() for k, v in kwargs.items(): if k == "xl": assert len(kwargs) == 1 self._xl = v elif k == "greg" in kwargs: assert len(kwargs) == 1 self._greg = v elif "dt" in kwargs: assert len(kwargs) == 1 self._dt = v elif k == "d": self._d = v elif k == "m": self._m = v elif k == "y": self._y = v elif k == "hh": self._hh = v elif k == "mm": self._mm = v elif k == "ss": self._ss = v elif k == "ms": assert self._us is None self._us = v * 1000 elif k == "us": assert self._us is None self._us = v else: raise AttributeError("Unknown attribute in __init__ kwargs")
def _parseIso8601String(date): """ Parses the given ISO 8601 string and returns a time tuple. The strings should be formatted according to RFC 3339 (see section 5.6). But currently there are two exceptions: 1. Time offset is limited to "Z". 2. Fragments of seconds are ignored. """ if "." in date and "Z" in date: # Contains fragments of second? secondFragmentPos = date.rfind(".") timeOffsetPos = date.rfind("Z") date = date[:secondFragmentPos] + date[timeOffsetPos:] try: timeTuple = time.strptime(date, Constants.DATE_FORMAT_ISO8601) except IllegalArgumentException: # Handling Jython 2.5 bug concerning the date pattern accordingly import _strptime # Using the Jython fall back solution directly timeTuple = _strptime.strptime(date, Constants.DATE_FORMAT_ISO8601) return timeTuple
def gregFromString(dateString, format="%d/%m/%Y"): """format codes: %a - abbreviated weekday name %A - full weekday name %b - abbreviated month name %B - full month name %c - preferred date and time representation %C - century number (the year divided by 100, range 00 to 99) %d - day of the month (01 to 31) %D - same as %m/%d/%y %e - day of the month (1 to 31) %g - like %G, but without the century %G - 4-digit year corresponding to the ISO week number (see %V). %h - same as %b %H - hour, using a 24-hour clock (00 to 23) %I - hour, using a 12-hour clock (01 to 12) %j - day of the year (001 to 366) %m - month (01 to 12) %M - minute %n - newline character %p - either am or pm according to the given time value %r - time in a.m. and p.m. notation %R - time in 24 hour notation %S - second %t - tab character %T - current time, equal to %H:%M:%S %u - weekday as a number (1 to 7), Monday=1. Warning: In Sun Solaris Sunday=1 %U - week number of the current year, starting with the first Sunday as the first day of the first week %V - The ISO 8601 week number of the current year (01 to 53), where week 1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week %W - week number of the current year, starting with the first Monday as the first day of the first week %w - day of the week as a decimal, Sunday=0 %x - preferred date representation without the time %X - preferred time representation without the date %y - year without a century (range 00 to 99) %Y - year including the century %Z or %z - time zone or name or abbreviation %% - a literal % character """ st = strptime(dateString, format) if _version == 27: st = st[0] return datetime(st.tm_year, st.tm_mon, st.tm_mday, st.tm_hour, st.tm_min, st.tm_sec).toordinal()
def test_bad_timezone(self): # Explicitly test possibility of bad timezone; # when time.tzname[0] == time.tzname[1] and time.daylight if sys.platform == "mac": return #MacOS9 has severely broken timezone support. tz_name = time.tzname[0] if tz_name.upper() in ("UTC", "GMT"): return try: original_tzname = time.tzname original_daylight = time.daylight time.tzname = (tz_name, tz_name) time.daylight = 1 tz_value = _strptime.strptime(tz_name, "%Z")[8] self.failUnlessEqual(tz_value, -1, "%s lead to a timezone value of %s instead of -1 when " "time.daylight set to %s and passing in %s" % (time.tzname, tz_value, time.daylight, tz_name)) finally: time.tzname = original_tzname time.daylight = original_daylight
def test_bad_timezone(self): # Explicitly test possibility of bad timezone; # when time.tzname[0] == time.tzname[1] and time.daylight if sys.platform == "mac": return # MacOS9 has severely broken timezone support. try: original_tzname = time.tzname original_daylight = time.daylight time.tzname = ("PDT", "PDT") time.daylight = 1 # Need to make sure that timezone is not calculated since that # calls time.tzset and overrides temporary changes to time . _strptime._locale_cache = _strptime.TimeRE(_strptime.LocaleTime( timezone=("PDT", "PDT"))) _strptime._regex_cache.clear() tz_value = _strptime.strptime("PDT", "%Z")[8] self.failUnlessEqual(tz_value, -1) finally: time.tzname = original_tzname time.daylight = original_daylight _strptime._locale_cache = _strptime.TimeRE() _strptime._regex_cache.clear()
def test_bad_timezone(self): # Explicitly test possibility of bad timezone; # when time.tzname[0] == time.tzname[1] and time.daylight if sys.platform == "mac": return # MacOS9 has severely broken timezone support. try: original_tzname = time.tzname original_daylight = time.daylight time.tzname = ("PDT", "PDT") time.daylight = 1 # Need to make sure that timezone is not calculated since that # calls time.tzset and overrides temporary changes to time . _strptime._locale_cache = _strptime.TimeRE( _strptime.LocaleTime(timezone=("PDT", "PDT"))) _strptime._regex_cache.clear() tz_value = _strptime.strptime("PDT", "%Z")[8] self.failUnlessEqual(tz_value, -1) finally: time.tzname = original_tzname time.daylight = original_daylight _strptime._locale_cache = _strptime.TimeRE() _strptime._regex_cache.clear()
def test_all_julian_days(self): eq = self.assertEqual for i in range(1, 367): # use 2004, since it is a leap year, we have 366 days eq(_strptime.strptime('%d 2004' % i, '%j %Y')[7], i)
def test_twelve_noon_midnight(self): eq = self.assertEqual eq(time.strptime('12 PM', '%I %p')[3], 12) eq(time.strptime('12 AM', '%I %p')[3], 0) eq(_strptime.strptime('12 PM', '%I %p')[3], 12) eq(_strptime.strptime('12 AM', '%I %p')[3], 0)