Merge lp:~fgallaire/bzr/fix-gmtime-lite into lp:bzr
- fix-gmtime-lite
- Merge into bzr.dev
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Vincent Ladeuil | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | 6622 | ||||||||
Proposed branch: | lp:~fgallaire/bzr/fix-gmtime-lite | ||||||||
Merge into: | lp:bzr | ||||||||
Diff against target: |
228 lines (+60/-18) 9 files modified
bzrlib/annotate.py (+1/-1) bzrlib/crash.py (+1/-1) bzrlib/doc_generate/autodoc_bash_completion.py (+2/-2) bzrlib/doc_generate/autodoc_man.py (+2/-2) bzrlib/doc_generate/autodoc_rstx.py (+1/-2) bzrlib/osutils.py (+15/-4) bzrlib/tests/blackbox/test_commit.py (+34/-1) bzrlib/timestamp.py (+1/-5) doc/en/release-notes/bzr-2.8.txt (+3/-0) |
||||||||
To merge this branch: | bzr merge lp:~fgallaire/bzr/fix-gmtime-lite | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Vincent Ladeuil | Approve | ||
Richard Wilbur | Approve | ||
Review via email: mp+318653@code.launchpad.net |
Commit message
Fix for Windows and 32-bit platforms buggy gmtime().
Description of the change
Fix for Windows buggy gmtime()
Fix for 32-bit platforms gmtime()
Light implementation
Richard Wilbur (richard-wilbur) wrote : | # |
Florent Gallaire (fgallaire) wrote : | # |
No open bug, it is necessary to file one ?
Richard Wilbur (richard-wilbur) wrote : | # |
We like to keep track of defects using bugs: steps to reproduce help developers diagnose the issue and also write good tests. Since we use Test-Driven Development we prefer to demonstrate an issue with a failing test case. Then a good fix solves the failing test without making any others fail.
Richard Wilbur (richard-wilbur) wrote : | # |
Thank you for coding up a solution.
Did you notice this as a bug in the operation of bzr or are you fixing the issue mentioned in the code?
If you would like assistance filing a bug report or creating a test case, please let me know.
Florent Gallaire (fgallaire) wrote : | # |
Richard, I didn't notice this in the operation of bzr as I don't use Windows, but you can easily test it.
This is the bug mentioned in the code, I have already fixed it in Mercurial:
https:/
Florent Gallaire (fgallaire) wrote : | # |
I have filed a bug report:
https:/
Florent Gallaire (fgallaire) wrote : | # |
Very unhappy with your Test-Driven Development practice because I was trying to make code cleaner and found that:
http://
Vincent Ladeuil (vila) wrote : | # |
> but you can easily test it.
No we can't (at least I and Richard can't).
That's the issue here, without testing on windows, nothing can really be fixed.
> Very unhappy with your Test-Driven Development practice because I was trying to make code cleaner and found that:
What is making you unhappy ?
Florent Gallaire (fgallaire) wrote : | # |
> > but you can easily test it.
>
> No we can't (at least I and Richard can't).
> That's the issue here, without testing on windows, nothing can really be
> fixed.
I have set up a Windows VM, you can see a screenshot of the bug in the report I filed.
> > Very unhappy with your Test-Driven Development practice because I was trying
> to make code cleaner and found that:
>
> What is making you unhappy ?
Look at the commit: awful replicated and spaghetti code justified by an useless test.
Vincent Ladeuil (vila) wrote : | # |
> > > but you can easily test it.
> >
> > No we can't (at least I and Richard can't).
> > That's the issue here, without testing on windows, nothing can really be
> > fixed.
>
> I have set up a Windows VM, you can see a screenshot of the bug in the report
> I filed.
Ha, that explains it, I receive bug reports by mail and rarely looked at attachment.
Copy/pasting the text was not an option ? It would make citing your bug report easier rather than having to type what is in the screenshot:
> bzr 2.6b1 python 2.6.6 (Windows-
Neither bzr-2.6 nor python2.6 are supported anymore.
> > > Very unhappy with your Test-Driven Development practice because I was
> trying
> > to make code cleaner and found that:
> >
> > What is making you unhappy ?
>
> Look at the commit: awful replicated and spaghetti code justified by an
> useless test.
Oook.
So, I didn't write that code nor that test so I won't take that personally.
Now, if you expect any project contributor to welcome your own contribution, it may be a good idea to not insult their work to start with.
Since you have a way to reproduce the issue though, and know how to TDD better than us, we'll welcome a a test reproducing that issue with the current code base (as mentioned above 2.6b1 has EOL'ed long ago) and a fix making the test pass.
Florent Gallaire (fgallaire) wrote : | # |
> > bzr 2.6b1 python 2.6.6 (Windows-
>
> Neither bzr-2.6 nor python2.6 are supported anymore.
I have installed the last version packaged for Windows to show you the bug:
http://
So in fact, is bazaar still supporting the Windows platform ?
> So, I didn't write that code nor that test so I won't take that personally.
>
> Now, if you expect any project contributor to welcome your own contribution,
> it may be a good idea to not insult their work to start with.
No offence, and no insult here. The author of the commit himself has commented that this was replicated code and for the only reason to make the test working... anyway it isn't the point.
Vincent Ladeuil (vila) wrote : | # |
> So in fact, is bazaar still supporting the Windows platform ?
See mailing archives for details. At this point the last installer is for 2.6b1 (b for beta).
A contributor willing to build a new installer and as such restore the release pipeline for windows would be highly welcome.
Florent Gallaire (fgallaire) wrote : | # |
tests added, ready to merge
Vincent Ladeuil (vila) wrote : | # |
Good work thanks !
I'm (pleasantly) surprised that this ends up being so lite (and focused).
As a side effect, it shows that bzr doesn't care about dates (which can't be guaranteed to be accurate in a distributed environment where host clocks can't be trusted).
grepping for 'gmtime(' I found a few references you probably want to fix too:
./bzrlib/
./bzrlib/
./bzrlib/
./bzrlib/
(I don't think they matter as much but being consistent and using osutils.gmtime() instead of time.gmtime() remove confusion about why the code base would use two different versions).
This bug fix is worth mentioning in the news in doc/en/
Final administrativia: please sign the CLA https:/
Florent Gallaire (fgallaire) wrote : | # |
> Good work thanks !
Thanks
> ./bzrlib/
> ./bzrlib/
> ./bzrlib/
> ./bzrlib/
> time.gmtime())
>
> (I don't think they matter as much but being consistent and using
> osutils.gmtime() instead of time.gmtime() remove confusion about why the code
> base would use two different versions).
I haven't replaced time.gmtime() and time.gmtime(
Do you want I fix it even so ?
> Final administrativia: please sign the CLA
> https:/
Done
Richard Wilbur (richard-wilbur) wrote : | # |
@Florent: Thank you for filing the bugs and creating the tests.
Since these problems have our attention presently, go ahead and fix the 4 files still using time.gmtime to use your new implementation in osutils.gmtime. Then we will be consistently using osutils.gmtime and won't have this particular issue in 20+ years should we still have users running bzr on 32-bit platforms at that time. (fairly likely)
Vincent Ladeuil (vila) wrote : | # |
In addition to what Richard said, having a single call makes it easier for newcomers to use the right one without having to research which one is appropriate for their case.
By the way, adding a docstring to osutils.gmtime() seems like the right way to achieve that. Nothing exotic, just mentioning why using time.gmtime() is not appropriate and why using osutils.gmtime() is better.
Florent Gallaire (fgallaire) wrote : | # |
Should be good now.
Richard Wilbur (richard-wilbur) wrote : | # |
Thank you for the fix to some problems I didn't know we had. Thank you also for the explanatory docstring and updating the rest of the code to use the fix.
I have no further reservations about merging this.
+1
@Vincent: Should we target 7.1 and then merge up to trunk?
Vincent Ladeuil (vila) wrote : | # |
Thanks !
> Should we target 7.1 and then merge up to trunk?
No, it's not a critical issue and almost a new feature, so... trunk is appropriate.
Will land asap.
Florent Gallaire (fgallaire) wrote : | # |
Thanks @Richard and @Vincent, happy to work with you.
bzr PQM (bzr-pqm) wrote : | # |
The attempt to merge lp:~fgallaire/bzr/fix-gmtime-lite into lp:bzr failed. Below is the output from the failed tests.
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
python tools/rst2html.py --link-stylesheet --footnote-
Florent Gallaire (fgallaire) wrote : | # |
Unremoved the needed time import. Tests run fine now.
Preview Diff
1 | === modified file 'bzrlib/annotate.py' | |||
2 | --- bzrlib/annotate.py 2012-06-26 12:14:56 +0000 | |||
3 | +++ bzrlib/annotate.py 2017-03-17 10:40:31 +0000 | |||
4 | @@ -215,7 +215,7 @@ | |||
5 | 215 | rev = revisions[origin] | 215 | rev = revisions[origin] |
6 | 216 | tz = rev.timezone or 0 | 216 | tz = rev.timezone or 0 |
7 | 217 | date_str = time.strftime('%Y%m%d', | 217 | date_str = time.strftime('%Y%m%d', |
9 | 218 | time.gmtime(rev.timestamp + tz)) | 218 | osutils.gmtime(rev.timestamp + tz)) |
10 | 219 | # a lazy way to get something like the email address | 219 | # a lazy way to get something like the email address |
11 | 220 | # TODO: Get real email address | 220 | # TODO: Get real email address |
12 | 221 | author = rev.get_apparent_authors()[0] | 221 | author = rev.get_apparent_authors()[0] |
13 | 222 | 222 | ||
14 | === modified file 'bzrlib/crash.py' | |||
15 | --- bzrlib/crash.py 2013-01-30 05:55:38 +0000 | |||
16 | +++ bzrlib/crash.py 2017-03-17 10:40:31 +0000 | |||
17 | @@ -242,7 +242,7 @@ | |||
18 | 242 | # Windows or if it's manually configured it might need to be created, | 242 | # Windows or if it's manually configured it might need to be created, |
19 | 243 | # and then it should be private | 243 | # and then it should be private |
20 | 244 | os.makedirs(crash_dir, mode=0600) | 244 | os.makedirs(crash_dir, mode=0600) |
22 | 245 | date_string = time.strftime('%Y-%m-%dT%H:%M', time.gmtime()) | 245 | date_string = time.strftime('%Y-%m-%dT%H:%M', osutils.gmtime()) |
23 | 246 | # XXX: getuid doesn't work on win32, but the crash directory is per-user | 246 | # XXX: getuid doesn't work on win32, but the crash directory is per-user |
24 | 247 | if sys.platform == 'win32': | 247 | if sys.platform == 'win32': |
25 | 248 | user_part = '' | 248 | user_part = '' |
26 | 249 | 249 | ||
27 | === modified file 'bzrlib/doc_generate/autodoc_bash_completion.py' | |||
28 | --- bzrlib/doc_generate/autodoc_bash_completion.py 2011-12-19 13:23:58 +0000 | |||
29 | +++ bzrlib/doc_generate/autodoc_bash_completion.py 2017-03-17 10:40:31 +0000 | |||
30 | @@ -23,6 +23,7 @@ | |||
31 | 23 | import bzrlib | 23 | import bzrlib |
32 | 24 | import bzrlib.help | 24 | import bzrlib.help |
33 | 25 | import bzrlib.commands | 25 | import bzrlib.commands |
34 | 26 | import bzrlib.osutils | ||
35 | 26 | 27 | ||
36 | 27 | 28 | ||
37 | 28 | def get_filename(options): | 29 | def get_filename(options): |
38 | @@ -30,8 +31,7 @@ | |||
39 | 30 | 31 | ||
40 | 31 | 32 | ||
41 | 32 | def infogen(options, outfile): | 33 | def infogen(options, outfile): |
44 | 33 | t = time.time() | 34 | tt = bzrlib.osutils.gmtime() |
43 | 34 | tt = time.gmtime(t) | ||
45 | 35 | params = \ | 35 | params = \ |
46 | 36 | { "bzrcmd": options.bzr_name, | 36 | { "bzrcmd": options.bzr_name, |
47 | 37 | "datestamp": time.strftime("%Y-%m-%d",tt), | 37 | "datestamp": time.strftime("%Y-%m-%d",tt), |
48 | 38 | 38 | ||
49 | === modified file 'bzrlib/doc_generate/autodoc_man.py' | |||
50 | --- bzrlib/doc_generate/autodoc_man.py 2015-03-14 23:44:01 +0000 | |||
51 | +++ bzrlib/doc_generate/autodoc_man.py 2017-03-17 10:40:31 +0000 | |||
52 | @@ -32,6 +32,7 @@ | |||
53 | 32 | import bzrlib.help | 32 | import bzrlib.help |
54 | 33 | import bzrlib.help_topics | 33 | import bzrlib.help_topics |
55 | 34 | import bzrlib.commands | 34 | import bzrlib.commands |
56 | 35 | import bzrlib.osutils | ||
57 | 35 | 36 | ||
58 | 36 | from bzrlib.plugin import load_plugins | 37 | from bzrlib.plugin import load_plugins |
59 | 37 | load_plugins() | 38 | load_plugins() |
60 | @@ -44,8 +45,7 @@ | |||
61 | 44 | 45 | ||
62 | 45 | def infogen(options, outfile): | 46 | def infogen(options, outfile): |
63 | 46 | """Assembles a man page""" | 47 | """Assembles a man page""" |
66 | 47 | t = time.time() | 48 | tt = bzrlib.osutils.gmtime() |
65 | 48 | tt = time.gmtime(t) | ||
67 | 49 | params = \ | 49 | params = \ |
68 | 50 | { "bzrcmd": options.bzr_name, | 50 | { "bzrcmd": options.bzr_name, |
69 | 51 | "datestamp": time.strftime("%Y-%m-%d",tt), | 51 | "datestamp": time.strftime("%Y-%m-%d",tt), |
70 | 52 | 52 | ||
71 | === modified file 'bzrlib/doc_generate/autodoc_rstx.py' | |||
72 | --- bzrlib/doc_generate/autodoc_rstx.py 2015-11-15 02:30:05 +0000 | |||
73 | +++ bzrlib/doc_generate/autodoc_rstx.py 2017-03-17 10:40:31 +0000 | |||
74 | @@ -38,8 +38,7 @@ | |||
75 | 38 | 38 | ||
76 | 39 | def infogen(options, outfile): | 39 | def infogen(options, outfile): |
77 | 40 | """Create manual in RSTX format""" | 40 | """Create manual in RSTX format""" |
80 | 41 | t = time.time() | 41 | tt = bzrlib.osutils.gmtime() |
79 | 42 | tt = time.gmtime(t) | ||
81 | 43 | params = \ | 42 | params = \ |
82 | 44 | { "bzrcmd": options.bzr_name, | 43 | { "bzrcmd": options.bzr_name, |
83 | 45 | "datestamp": time.strftime("%Y-%m-%d",tt), | 44 | "datestamp": time.strftime("%Y-%m-%d",tt), |
84 | 46 | 45 | ||
85 | === modified file 'bzrlib/osutils.py' | |||
86 | --- bzrlib/osutils.py 2013-06-24 12:03:12 +0000 | |||
87 | +++ bzrlib/osutils.py 2017-03-17 10:40:31 +0000 | |||
88 | @@ -27,6 +27,7 @@ | |||
89 | 27 | from bzrlib.lazy_import import lazy_import | 27 | from bzrlib.lazy_import import lazy_import |
90 | 28 | lazy_import(globals(), """ | 28 | lazy_import(globals(), """ |
91 | 29 | from datetime import datetime | 29 | from datetime import datetime |
92 | 30 | from datetime import timedelta | ||
93 | 30 | import getpass | 31 | import getpass |
94 | 31 | import locale | 32 | import locale |
95 | 32 | import ntpath | 33 | import ntpath |
96 | @@ -827,6 +828,16 @@ | |||
97 | 827 | return True | 828 | return True |
98 | 828 | 829 | ||
99 | 829 | 830 | ||
100 | 831 | def gmtime(seconds=None): | ||
101 | 832 | """Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a. | ||
102 | 833 | GMT). When 'seconds' is not passed in, convert the current time instead. | ||
103 | 834 | Handy replacement for time.gmtime() buggy on Windows and 32-bit platforms. | ||
104 | 835 | """ | ||
105 | 836 | if seconds is None: | ||
106 | 837 | seconds = time.time() | ||
107 | 838 | return (datetime(1970, 1, 1) + timedelta(seconds=seconds)).timetuple() | ||
108 | 839 | |||
109 | 840 | |||
110 | 830 | def local_time_offset(t=None): | 841 | def local_time_offset(t=None): |
111 | 831 | """Return offset of local zone from GMT, either at present or at time t.""" | 842 | """Return offset of local zone from GMT, either at present or at time t.""" |
112 | 832 | if t is None: | 843 | if t is None: |
113 | @@ -872,7 +883,7 @@ | |||
114 | 872 | """ | 883 | """ |
115 | 873 | if offset is None: | 884 | if offset is None: |
116 | 874 | offset = 0 | 885 | offset = 0 |
118 | 875 | tt = time.gmtime(t + offset) | 886 | tt = gmtime(t + offset) |
119 | 876 | date_fmt = _default_format_by_weekday_num[tt[6]] | 887 | date_fmt = _default_format_by_weekday_num[tt[6]] |
120 | 877 | date_str = time.strftime(date_fmt, tt) | 888 | date_str = time.strftime(date_fmt, tt) |
121 | 878 | offset_str = _cache.get(offset, None) | 889 | offset_str = _cache.get(offset, None) |
122 | @@ -904,12 +915,12 @@ | |||
123 | 904 | 915 | ||
124 | 905 | def _format_date(t, offset, timezone, date_fmt, show_offset): | 916 | def _format_date(t, offset, timezone, date_fmt, show_offset): |
125 | 906 | if timezone == 'utc': | 917 | if timezone == 'utc': |
127 | 907 | tt = time.gmtime(t) | 918 | tt = gmtime(t) |
128 | 908 | offset = 0 | 919 | offset = 0 |
129 | 909 | elif timezone == 'original': | 920 | elif timezone == 'original': |
130 | 910 | if offset is None: | 921 | if offset is None: |
131 | 911 | offset = 0 | 922 | offset = 0 |
133 | 912 | tt = time.gmtime(t + offset) | 923 | tt = gmtime(t + offset) |
134 | 913 | elif timezone == 'local': | 924 | elif timezone == 'local': |
135 | 914 | tt = time.localtime(t) | 925 | tt = time.localtime(t) |
136 | 915 | offset = local_time_offset(t) | 926 | offset = local_time_offset(t) |
137 | @@ -925,7 +936,7 @@ | |||
138 | 925 | 936 | ||
139 | 926 | 937 | ||
140 | 927 | def compact_date(when): | 938 | def compact_date(when): |
142 | 928 | return time.strftime('%Y%m%d%H%M%S', time.gmtime(when)) | 939 | return time.strftime('%Y%m%d%H%M%S', gmtime(when)) |
143 | 929 | 940 | ||
144 | 930 | 941 | ||
145 | 931 | def format_delta(delta): | 942 | def format_delta(delta): |
146 | 932 | 943 | ||
147 | === modified file 'bzrlib/tests/blackbox/test_commit.py' | |||
148 | --- bzrlib/tests/blackbox/test_commit.py 2016-02-01 18:06:32 +0000 | |||
149 | +++ bzrlib/tests/blackbox/test_commit.py 2017-03-17 10:40:31 +0000 | |||
150 | @@ -713,7 +713,40 @@ | |||
151 | 713 | self.assertEqual( | 713 | self.assertEqual( |
152 | 714 | 'Sat 2009-10-10 08:00:00 +0100', | 714 | 'Sat 2009-10-10 08:00:00 +0100', |
153 | 715 | osutils.format_date(last_rev.timestamp, last_rev.timezone)) | 715 | osutils.format_date(last_rev.timestamp, last_rev.timezone)) |
155 | 716 | 716 | ||
156 | 717 | def test_commit_time_negative_windows(self): | ||
157 | 718 | tree = self.make_branch_and_tree('tree') | ||
158 | 719 | self.build_tree(['tree/hello.txt']) | ||
159 | 720 | tree.add('hello.txt') | ||
160 | 721 | out, err = self.run_bzr("commit -m hello " | ||
161 | 722 | "--commit-time='1969-10-10 00:00:00 +0000' tree/hello.txt") | ||
162 | 723 | last_rev = tree.branch.repository.get_revision(tree.last_revision()) | ||
163 | 724 | self.assertEqual( | ||
164 | 725 | 'Fri 1969-10-10 00:00:00 +0000', | ||
165 | 726 | osutils.format_date(last_rev.timestamp, last_rev.timezone)) | ||
166 | 727 | |||
167 | 728 | def test_commit_time_negative_32bit(self): | ||
168 | 729 | tree = self.make_branch_and_tree('tree') | ||
169 | 730 | self.build_tree(['tree/hello.txt']) | ||
170 | 731 | tree.add('hello.txt') | ||
171 | 732 | out, err = self.run_bzr("commit -m hello " | ||
172 | 733 | "--commit-time='1900-01-01 00:00:00 +0000' tree/hello.txt") | ||
173 | 734 | last_rev = tree.branch.repository.get_revision(tree.last_revision()) | ||
174 | 735 | self.assertEqual( | ||
175 | 736 | 'Mon 1900-01-01 00:00:00 +0000', | ||
176 | 737 | osutils.format_date(last_rev.timestamp, last_rev.timezone)) | ||
177 | 738 | |||
178 | 739 | def test_commit_time_positive_32bit(self): | ||
179 | 740 | tree = self.make_branch_and_tree('tree') | ||
180 | 741 | self.build_tree(['tree/hello.txt']) | ||
181 | 742 | tree.add('hello.txt') | ||
182 | 743 | out, err = self.run_bzr("commit -m hello " | ||
183 | 744 | "--commit-time='2039-01-01 00:00:00 +0000' tree/hello.txt") | ||
184 | 745 | last_rev = tree.branch.repository.get_revision(tree.last_revision()) | ||
185 | 746 | self.assertEqual( | ||
186 | 747 | 'Sat 2039-01-01 00:00:00 +0000', | ||
187 | 748 | osutils.format_date(last_rev.timestamp, last_rev.timezone)) | ||
188 | 749 | |||
189 | 717 | def test_commit_time_bad_time(self): | 750 | def test_commit_time_bad_time(self): |
190 | 718 | tree = self.make_branch_and_tree('tree') | 751 | tree = self.make_branch_and_tree('tree') |
191 | 719 | self.build_tree(['tree/hello.txt']) | 752 | self.build_tree(['tree/hello.txt']) |
192 | 720 | 753 | ||
193 | === modified file 'bzrlib/timestamp.py' | |||
194 | --- bzrlib/timestamp.py 2011-12-18 15:28:38 +0000 | |||
195 | +++ bzrlib/timestamp.py 2017-03-17 10:40:31 +0000 | |||
196 | @@ -57,7 +57,7 @@ | |||
197 | 57 | # revision XML entry will be reproduced faithfully. | 57 | # revision XML entry will be reproduced faithfully. |
198 | 58 | if offset is None: | 58 | if offset is None: |
199 | 59 | offset = 0 | 59 | offset = 0 |
201 | 60 | tt = time.gmtime(t + offset) | 60 | tt = osutils.gmtime(t + offset) |
202 | 61 | 61 | ||
203 | 62 | return (osutils.weekdays[tt[6]] + | 62 | return (osutils.weekdays[tt[6]] + |
204 | 63 | time.strftime(" %Y-%m-%d %H:%M:%S", tt) | 63 | time.strftime(" %Y-%m-%d %H:%M:%S", tt) |
205 | @@ -119,10 +119,6 @@ | |||
206 | 119 | # give the epoch in utc | 119 | # give the epoch in utc |
207 | 120 | if secs == 0: | 120 | if secs == 0: |
208 | 121 | offset = 0 | 121 | offset = 0 |
209 | 122 | if secs + offset < 0: | ||
210 | 123 | from warnings import warn | ||
211 | 124 | warn("gmtime of negative time (%s, %s) may not work on Windows" % | ||
212 | 125 | (secs, offset)) | ||
213 | 126 | return osutils.format_date(secs, offset=offset, | 122 | return osutils.format_date(secs, offset=offset, |
214 | 127 | date_fmt='%Y-%m-%d %H:%M:%S') | 123 | date_fmt='%Y-%m-%d %H:%M:%S') |
215 | 128 | 124 | ||
216 | 129 | 125 | ||
217 | === modified file 'doc/en/release-notes/bzr-2.8.txt' | |||
218 | --- doc/en/release-notes/bzr-2.8.txt 2017-01-17 15:02:46 +0000 | |||
219 | +++ doc/en/release-notes/bzr-2.8.txt 2017-03-17 10:40:31 +0000 | |||
220 | @@ -36,6 +36,9 @@ | |||
221 | 36 | doc/en/user-reference only contains English documentation. | 36 | doc/en/user-reference only contains English documentation. |
222 | 37 | (Jelmer Vernooij, #1565503) | 37 | (Jelmer Vernooij, #1565503) |
223 | 38 | 38 | ||
224 | 39 | * Fix for Windows and 32-bit platforms buggy gmtime(). | ||
225 | 40 | (Florent Gallaire, #1669178, #1670243) | ||
226 | 41 | |||
227 | 39 | Documentation | 42 | Documentation |
228 | 40 | ************* | 43 | ************* |
229 | 41 | 44 |
Have you filed a bug report for this problem? Or if it is already filed as a bug, let's link it here.