diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2016-04-20 09:00:25 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2016-04-20 09:00:25 +0200 |
commit | d04aeaa17e628f13d1a590a32ae96bc7d35775b5 (patch) | |
tree | 36ea8e5dd06b5e8c671e39a2185675042787ef38 | |
parent | fcb6e8832a94776d670095935a7da579a111c028 (diff) | |
parent | f77f9775277a100c7809698c75cb0855b07b884d (diff) | |
download | gitpython-d04aeaa17e628f13d1a590a32ae96bc7d35775b5.tar.gz |
Merge pull request #414 from nvie/support-full-datetimes-on-commits
Add support for getting "aware" datetime info
-rw-r--r-- | git/objects/commit.py | 11 | ||||
-rw-r--r-- | git/objects/util.py | 30 | ||||
-rw-r--r-- | git/test/test_commit.py | 11 |
3 files changed, 50 insertions, 2 deletions
diff --git a/git/objects/commit.py b/git/objects/commit.py index d067b718..dc722f97 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -21,7 +21,8 @@ from .util import ( Serializable, parse_date, altz_to_utctz_str, - parse_actor_and_date + parse_actor_and_date, + from_timestamp, ) from git.compat import text_type @@ -145,6 +146,14 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable): # END handle attrs @property + def authored_datetime(self): + return from_timestamp(self.authored_date, self.author_tz_offset) + + @property + def committed_datetime(self): + return from_timestamp(self.committed_date, self.committer_tz_offset) + + @property def summary(self): """:return: First line of the commit message""" return self.message.split('\n', 1)[0] diff --git a/git/objects/util.py b/git/objects/util.py index 8fd92a0a..cbb9fe3c 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -15,10 +15,13 @@ from collections import deque as Deque from string import digits import time import calendar +from datetime import datetime, timedelta, tzinfo __all__ = ('get_object_type_by_name', 'parse_date', 'parse_actor_and_date', 'ProcessStreamAdapter', 'Traversable', 'altz_to_utctz_str', 'utctz_to_altz', - 'verify_utctz', 'Actor') + 'verify_utctz', 'Actor', 'tzoffset', 'utc') + +ZERO = timedelta(0) #{ Functions @@ -97,6 +100,31 @@ def verify_utctz(offset): return offset +class tzoffset(tzinfo): + def __init__(self, secs_west_of_utc, name=None): + self._offset = timedelta(seconds=-secs_west_of_utc) + self._name = name or 'fixed' + + def utcoffset(self, dt): + return self._offset + + def tzname(self, dt): + return self._name + + def dst(self, dt): + return ZERO + + +utc = tzoffset(0, 'UTC') + + +def from_timestamp(timestamp, tz_offset): + """Converts a timestamp + tz_offset into an aware datetime instance.""" + utc_dt = datetime.fromtimestamp(timestamp, utc) + local_dt = utc_dt.astimezone(tzoffset(tz_offset)) + return local_dt + + def parse_date(string_date): """ Parse the given date as one of the following diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 3e958edf..23b7154a 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -32,6 +32,8 @@ import time import sys import re import os +from datetime import datetime +from git.objects.util import tzoffset, utc def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False): @@ -343,3 +345,12 @@ JzJMZDRLQLFvnzqZuCjE cstream = BytesIO() cmt._serialize(cstream) assert not re.search(r"^gpgsig ", cstream.getvalue().decode('ascii'), re.MULTILINE) + + def test_datetimes(self): + commit = self.rorepo.commit('4251bd5') + assert commit.authored_date == 1255018625 + assert commit.committed_date == 1255026171 + assert commit.authored_datetime == datetime(2009, 10, 8, 18, 17, 5, tzinfo=tzoffset(-7200)), commit.authored_datetime # noqa + assert commit.authored_datetime == datetime(2009, 10, 8, 16, 17, 5, tzinfo=utc), commit.authored_datetime + assert commit.committed_datetime == datetime(2009, 10, 8, 20, 22, 51, tzinfo=tzoffset(-7200)) + assert commit.committed_datetime == datetime(2009, 10, 8, 18, 22, 51, tzinfo=utc), commit.committed_datetime |