Merge lp:~fgallaire/bzr/fix-localtime into lp:bzr

Proposed by Florent Gallaire on 2017-03-20
Status: Needs review
Proposed branch: lp:~fgallaire/bzr/fix-localtime
Merge into: lp:bzr
Diff against target: 79 lines (+34/-5)
3 files modified
bzrlib/osutils.py (+19/-5)
bzrlib/tests/test_osutils.py (+12/-0)
doc/en/release-notes/bzr-2.8.txt (+3/-0)
To merge this branch: bzr merge lp:~fgallaire/bzr/fix-localtime
Reviewer Review Type Date Requested Status
bzr-core 2017-03-20 Pending
Review via email: mp+320299@code.launchpad.net

Description of the Change

Fix buggy on Windows and 32-bit platforms local_time_offset().
_format_date() fail back to 'original' timezone when 'local' is buggy.

To post a comment you must log in.
lp:~fgallaire/bzr/fix-localtime updated on 2017-03-22
6623. By Florent Gallaire on 2017-03-22

Fix for Windows and 32-bit platforms buggy local_time_offset().

Unmerged revisions

6623. By Florent Gallaire on 2017-03-22

Fix for Windows and 32-bit platforms buggy local_time_offset().

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/osutils.py'
2--- bzrlib/osutils.py 2017-03-17 10:39:02 +0000
3+++ bzrlib/osutils.py 2017-03-22 04:32:31 +0000
4@@ -839,11 +839,18 @@
5
6
7 def local_time_offset(t=None):
8- """Return offset of local zone from GMT, either at present or at time t."""
9+ """Return offset of local zone from GMT, either at present or at time t.
10+ Return None if buggy gmtime() or localtime().
11+ """
12 if t is None:
13 t = time.time()
14- offset = datetime.fromtimestamp(t) - datetime.utcfromtimestamp(t)
15- return offset.days * 86400 + offset.seconds
16+ try:
17+ # datetime.fromtimestamp() and datetime.utcfromtimestamp() are as buggy
18+ # as time.gmtime(). Not fixable (https://bugs.python.org/issue1647654).
19+ offset = datetime.fromtimestamp(t) - datetime.utcfromtimestamp(t)
20+ return offset.days * 86400 + offset.seconds
21+ except ValueError:
22+ return None
23
24 weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
25 _default_format_by_weekday_num = [wd + " %Y-%m-%d %H:%M:%S" for wd in weekdays]
26@@ -922,8 +929,15 @@
27 offset = 0
28 tt = gmtime(t + offset)
29 elif timezone == 'local':
30- tt = time.localtime(t)
31- offset = local_time_offset(t)
32+ local_offset = local_time_offset(t)
33+ if local_offset:
34+ tt = time.localtime(t)
35+ offset = local_offset
36+ else:
37+ # If buggy, use 'original' timezone
38+ if offset is None:
39+ offset = 0
40+ tt = gmtime(t + offset)
41 else:
42 raise errors.UnsupportedTimezoneFormat(timezone)
43 if date_fmt is None:
44
45=== modified file 'bzrlib/tests/test_osutils.py'
46--- bzrlib/tests/test_osutils.py 2016-02-01 18:06:32 +0000
47+++ bzrlib/tests/test_osutils.py 2017-03-22 04:32:31 +0000
48@@ -436,6 +436,18 @@
49 eighteen_hours = 18 * 3600
50 self.assertTrue(-eighteen_hours < offset < eighteen_hours)
51
52+ def test_local_time_offset_with_negative_windows_timestamp(self):
53+ # Fri 1969-10-10 00:00:00 +0000
54+ offset = osutils.local_time_offset(-7171200)
55+
56+ def test_local_time_offset_with_negative_32bit_timestamp(self):
57+ # Mon 1900-01-01 00:00:00 +0000
58+ offset = osutils.local_time_offset(-2208988800)
59+
60+ def test_local_time_offset_with_positive_32bit_timestamp(self):
61+ # Sat 2039-01-01 00:00:00 +0000
62+ offset = osutils.local_time_offset(2177452800)
63+
64
65 class TestFdatasync(tests.TestCaseInTempDir):
66
67
68=== modified file 'doc/en/release-notes/bzr-2.8.txt'
69--- doc/en/release-notes/bzr-2.8.txt 2017-03-17 10:39:02 +0000
70+++ doc/en/release-notes/bzr-2.8.txt 2017-03-22 04:32:31 +0000
71@@ -39,6 +39,9 @@
72 * Fix for Windows and 32-bit platforms buggy gmtime().
73 (Florent Gallaire, #1669178, #1670243)
74
75+ * Fix for Windows and 32-bit platforms buggy local_time_offset().
76+ (Florent Gallaire, #1674195)
77+
78 Documentation
79 *************
80