diff options
author | Marko Kreen | 2013-03-23 12:13:51 +0000 |
---|---|---|
committer | Marko Kreen | 2013-03-23 12:13:51 +0000 |
commit | a7b8f516eb187e4649ce46df90629da52b9af04e (patch) | |
tree | 323eccf915c948bdaedbda3f49789748f49ca861 | |
parent | c2fcbff3f82307957c18d548e0b9228907787078 (diff) |
timeutil.datetime_to_timestamp: new function
converts datetime() to posix timestamp.
-rw-r--r-- | python/skytools/__init__.py | 1 | ||||
-rw-r--r-- | python/skytools/timeutil.py | 75 |
2 files changed, 64 insertions, 12 deletions
diff --git a/python/skytools/__init__.py b/python/skytools/__init__.py index 048d41fb..db5b2ba1 100644 --- a/python/skytools/__init__.py +++ b/python/skytools/__init__.py @@ -135,6 +135,7 @@ _symbols = { 'mk_update_sql': 'skytools.sqltools:mk_update_sql', # skytools.timeutil 'FixedOffsetTimezone': 'skytools.timeutil:FixedOffsetTimezone', + 'datetime_to_timestamp': 'skytools.timeutil:datetime_to_timestamp', 'parse_iso_timestamp': 'skytools.timeutil:parse_iso_timestamp', # skytools.utf8 'safe_utf8_decode': 'skytools.utf8:safe_utf8_decode', diff --git a/python/skytools/timeutil.py b/python/skytools/timeutil.py index b6728bf2..a29e050c 100644 --- a/python/skytools/timeutil.py +++ b/python/skytools/timeutil.py @@ -1,23 +1,20 @@ -"""Module for parsing ISO 8601 format timestamps. +"""Fill gaps in Python time API-s. -Only fixed offset timezones are supported. +parse_iso_timestamp: + Parse reasonable subset of ISO_8601 timestamp formats. + [ http://en.wikipedia.org/wiki/ISO_8601 ] + +datetime_to_timestamp: + Get POSIX timestamp from datetime() object. -http://en.wikipedia.org/wiki/ISO_8601 """ import re - +import time from datetime import datetime, timedelta, tzinfo -""" -TODO: -- support more combinations from ISO 8601 (only reasonable ones) -- cache TZ objects -- make it faster? -""" - -__all__ = ['parse_iso_timestamp', 'FixedOffsetTimezone'] +__all__ = ['parse_iso_timestamp', 'FixedOffsetTimezone', 'datetime_to_timestamp'] class FixedOffsetTimezone(tzinfo): """Fixed offset in minutes east from UTC.""" @@ -46,6 +43,17 @@ class FixedOffsetTimezone(tzinfo): ZERO = timedelta(0) +# +# Parse ISO_8601 timestamps. +# + +""" +TODO: +- support more combinations from ISO 8601 (only reasonable ones) +- cache TZ objects +- make it faster? +""" + _iso_regex = r""" \s* (?P<year> \d\d\d\d) [-] (?P<month> \d\d) [-] (?P<day> \d\d) [ T] @@ -67,6 +75,8 @@ def parse_iso_timestamp(s, default_tz = None): If the timezone offset is not present, use default_tz as tzinfo. By default its None, meaning the datetime object will be without tz. + Only fixed offset timezones are supported. + >>> str(parse_iso_timestamp('2005-06-01 15:00')) '2005-06-01 15:00:00' >>> str(parse_iso_timestamp(' 2005-06-01T15:00 +02 ')) @@ -108,6 +118,47 @@ def parse_iso_timestamp(s, default_tz = None): m.group('ss') and int(m.group('ss').ljust(6, '0')) or 0, tz) +# +# POSIX timestamp from datetime() +# + +UTC = FixedOffsetTimezone(0) +TZ_EPOCH = datetime.fromtimestamp(0, UTC) +UTC_NOTZ_EPOCH = datetime.utcfromtimestamp(0) + +def datetime_to_timestamp(dt, local_time=True): + """Get posix timestamp from datetime() object. + + if dt is without timezone, then local_time specifies + whether it's UTC or local time. + + Returns seconds since epoch as float. + + >>> datetime_to_timestamp(parse_iso_timestamp("2005-06-01 15:00:59.33 +02")) + 1117630859.33 + >>> datetime_to_timestamp(datetime.fromtimestamp(1117630859.33, UTC)) + 1117630859.33 + >>> datetime_to_timestamp(datetime.fromtimestamp(1117630859.33)) + 1117630859.33 + >>> now = datetime.utcnow() + >>> now2 = datetime.utcfromtimestamp(datetime_to_timestamp(now, False)) + >>> now == now2 + True + >>> now = datetime.now() + >>> now2 = datetime.fromtimestamp(datetime_to_timestamp(now)) + >>> now == now2 + True + """ + if dt.tzinfo: + delta = dt - TZ_EPOCH + return delta.total_seconds() + elif local_time: + s = time.mktime(dt.timetuple()) + return s + (dt.microsecond / 1000000.0) + else: + delta = dt - UTC_NOTZ_EPOCH + return delta.total_seconds() + if __name__ == '__main__': import doctest doctest.testmod() |