Commit 9f37f689 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

utils: Timezone fixes and tests



- Update docstrings to explicitely mention Epoch
- Fix timezone bug in FormatTimestampWithTZ, where it would
  use GMT/UTC when it should use the local timezone
- Add unittests for time formatting functions
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent b60fcb6f
...@@ -1680,8 +1680,8 @@ def RemoveHostFromEtcHosts(hostname): ...@@ -1680,8 +1680,8 @@ def RemoveHostFromEtcHosts(hostname):
def TimestampForFilename(): def TimestampForFilename():
"""Returns the current time formatted for filenames. """Returns the current time formatted for filenames.
The format doesn't contain colons as some shells and applications them as The format doesn't contain colons as some shells and applications treat them
separators. as separators. Uses the local timezone.
""" """
return time.strftime("%Y-%m-%d_%H_%M_%S") return time.strftime("%Y-%m-%d_%H_%M_%S")
...@@ -2838,8 +2838,11 @@ def TailFile(fname, lines=20): ...@@ -2838,8 +2838,11 @@ def TailFile(fname, lines=20):
def FormatTimestampWithTZ(secs): def FormatTimestampWithTZ(secs):
"""Formats a Unix timestamp with the local timezone. """Formats a Unix timestamp with the local timezone.
@type secs: number
@param secs: Seconds since the Epoch (1970-01-01 00:00:00 UTC)
""" """
return time.strftime("%F %T %Z", time.gmtime(secs)) return time.strftime("%F %T %Z", time.localtime(secs))
def _ParseAsn1Generalizedtime(value): def _ParseAsn1Generalizedtime(value):
...@@ -3366,7 +3369,8 @@ def FormatTime(val): ...@@ -3366,7 +3369,8 @@ def FormatTime(val):
"""Formats a time value. """Formats a time value.
@type val: float or None @type val: float or None
@param val: the timestamp as returned by time.time() @param val: Timestamp as returned by time.time() (seconds since Epoch,
1970-01-01 00:00:00 UTC)
@return: a string value or N/A if we don't have a valid timestamp @return: a string value or N/A if we don't have a valid timestamp
""" """
......
...@@ -1682,6 +1682,23 @@ class TestSafeEncode(unittest.TestCase): ...@@ -1682,6 +1682,23 @@ class TestSafeEncode(unittest.TestCase):
class TestFormatTime(unittest.TestCase): class TestFormatTime(unittest.TestCase):
"""Testing case for FormatTime""" """Testing case for FormatTime"""
@staticmethod
def _TestInProcess(tz, timestamp, expected):
os.environ["TZ"] = tz
time.tzset()
return utils.FormatTime(timestamp) == expected
def _Test(self, *args):
# Need to use separate process as we want to change TZ
self.assert_(utils.RunInSeparateProcess(self._TestInProcess, *args))
def test(self):
self._Test("UTC", 0, "1970-01-01 00:00:00")
self._Test("America/Sao_Paulo", 1292606926, "2010-12-17 15:28:46")
self._Test("Europe/London", 1292606926, "2010-12-17 17:28:46")
self._Test("Europe/Zurich", 1292606926, "2010-12-17 18:28:46")
self._Test("Australia/Sydney", 1292606926, "2010-12-18 04:28:46")
def testNone(self): def testNone(self):
self.failUnlessEqual(FormatTime(None), "N/A") self.failUnlessEqual(FormatTime(None), "N/A")
...@@ -1695,6 +1712,25 @@ class TestFormatTime(unittest.TestCase): ...@@ -1695,6 +1712,25 @@ class TestFormatTime(unittest.TestCase):
FormatTime(int(time.time())) FormatTime(int(time.time()))
class TestFormatTimestampWithTZ(unittest.TestCase):
@staticmethod
def _TestInProcess(tz, timestamp, expected):
os.environ["TZ"] = tz
time.tzset()
return utils.FormatTimestampWithTZ(timestamp) == expected
def _Test(self, *args):
# Need to use separate process as we want to change TZ
self.assert_(utils.RunInSeparateProcess(self._TestInProcess, *args))
def test(self):
self._Test("UTC", 0, "1970-01-01 00:00:00 UTC")
self._Test("America/Sao_Paulo", 1292606926, "2010-12-17 15:28:46 BRST")
self._Test("Europe/London", 1292606926, "2010-12-17 17:28:46 GMT")
self._Test("Europe/Zurich", 1292606926, "2010-12-17 18:28:46 CET")
self._Test("Australia/Sydney", 1292606926, "2010-12-18 04:28:46 EST")
class RunInSeparateProcess(unittest.TestCase): class RunInSeparateProcess(unittest.TestCase):
def test(self): def test(self):
for exp in [True, False]: for exp in [True, False]:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment