Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a2c8c7f

Browse filesBrowse files
committed
Add support for getting "aware" datetime info
This adds 2 properties to commits. Their values are derived from the existing data stored on them, but this makes them more conveniently queryable: - authored_datetime - committed_datetime These return "aware" datetimes, so they are effectively companions to their raw timestamp equivalents, respectively `authored_date` and `committed_date`. These datetime instances are convenient structures since they show the author-local commit date and their UTC offset.
1 parent 504870e commit a2c8c7f
Copy full SHA for a2c8c7f

4 files changed

+51-2Lines changed: 51 additions & 2 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎git/objects/commit.py‎

Copy file name to clipboardExpand all lines: git/objects/commit.py
+10-1Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
Serializable,
2222
parse_date,
2323
altz_to_utctz_str,
24-
parse_actor_and_date
24+
parse_actor_and_date,
25+
from_timestamp,
2526
)
2627
from git.compat import text_type
2728

@@ -144,6 +145,14 @@ def _set_cache_(self, attr):
144145
super(Commit, self)._set_cache_(attr)
145146
# END handle attrs
146147

148+
@property
149+
def authored_datetime(self):
150+
return from_timestamp(self.authored_date, self.author_tz_offset)
151+
152+
@property
153+
def committed_datetime(self):
154+
return from_timestamp(self.committed_date, self.committer_tz_offset)
155+
147156
@property
148157
def summary(self):
149158
""":return: First line of the commit message"""
Collapse file

‎git/objects/util.py‎

Copy file name to clipboardExpand all lines: git/objects/util.py
+29-1Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
from string import digits
1616
import time
1717
import calendar
18+
from datetime import datetime, timedelta, tzinfo
1819

1920
__all__ = ('get_object_type_by_name', 'parse_date', 'parse_actor_and_date',
2021
'ProcessStreamAdapter', 'Traversable', 'altz_to_utctz_str', 'utctz_to_altz',
21-
'verify_utctz', 'Actor')
22+
'verify_utctz', 'Actor', 'tzoffset', 'utc')
23+
24+
ZERO = timedelta(0)
2225

2326
#{ Functions
2427

@@ -97,6 +100,31 @@ def verify_utctz(offset):
97100
return offset
98101

99102

103+
class tzoffset(tzinfo):
104+
def __init__(self, secs_west_of_utc, name=None):
105+
self._offset = timedelta(seconds=-secs_west_of_utc)
106+
self._name = name or 'fixed'
107+
108+
def utcoffset(self, dt):
109+
return self._offset
110+
111+
def tzname(self, dt):
112+
return self._name
113+
114+
def dst(self, dt):
115+
return ZERO
116+
117+
118+
utc = tzoffset(0, 'UTC')
119+
120+
121+
def from_timestamp(timestamp, tz_offset):
122+
"""Converts a timestamp + tz_offset into an aware datetime instance."""
123+
utc_dt = datetime.fromtimestamp(timestamp, utc)
124+
local_dt = utc_dt.astimezone(tzoffset(tz_offset))
125+
return local_dt
126+
127+
100128
def parse_date(string_date):
101129
"""
102130
Parse the given date as one of the following
Collapse file

‎git/test/test_commit.py‎

Copy file name to clipboardExpand all lines: git/test/test_commit.py
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import sys
3333
import re
3434
import os
35+
from datetime import datetime
36+
from git.objects.util import tzoffset, utc
3537

3638

3739
def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False):
@@ -343,3 +345,12 @@ def test_gpgsig(self):
343345
cstream = BytesIO()
344346
cmt._serialize(cstream)
345347
assert not re.search(r"^gpgsig ", cstream.getvalue().decode('ascii'), re.MULTILINE)
348+
349+
def test_datetimes(self):
350+
commit = self.rorepo.commit('4251bd5')
351+
assert commit.authored_date == 1255018625
352+
assert commit.committed_date == 1255026171
353+
assert commit.authored_datetime == datetime(2009, 10, 8, 18, 17, 5, tzinfo=tzoffset(-7200)), commit.authored_datetime # noqa
354+
assert commit.authored_datetime == datetime(2009, 10, 8, 16, 17, 5, tzinfo=utc), commit.authored_datetime
355+
assert commit.committed_datetime == datetime(2009, 10, 8, 20, 22, 51, tzinfo=tzoffset(-7200))
356+
assert commit.committed_datetime == datetime(2009, 10, 8, 18, 22, 51, tzinfo=utc), commit.committed_datetime
Collapse file

‎git/test/test_util.py‎

Copy file name to clipboardExpand all lines: git/test/test_util.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
utctz_to_altz,
2323
verify_utctz,
2424
parse_date,
25+
tzoffset,
2526
)
2627
from git.cmd import dashify
2728
from git.compat import string_types

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.