classification
Title: strptime() can produce invalid date with negative year day
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: belopolsky, beng94, iaslan, lemburg, python-dev, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2015-03-20 11:30 by serhiy.storchaka, last changed 2016-03-12 08:55 by serhiy.storchaka. This issue is now closed.

Files
File name Uploaded Description Edit
julian_date.patch beng94, 2016-02-09 22:14 review
julian_date_v1.patch beng94, 2016-02-16 12:11 review
Messages (10)
msg238648 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-03-20 11:30
strptime() can produce invalid time with negative year day when parse year-week-weekday set. Such time is rejected by strftime(), so strptime/strftime roundtrip doesn't work.

>>> t = time.strptime('2015 0 0', '%Y %U %w')
>>> t
time.struct_time(tm_year=2014, tm_mon=12, tm_mday=28, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=-3, tm_isdst=-1)
>>> time.strftime('%Y %U %w', t)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: day of year out of range
msg259752 - (view) Author: Tamás Bence Gedai (beng94) * Date: 2016-02-06 23:17
It looks interesting, let me try to solve this. At first it seems odd that _calc_julian_from_U_or_W returns -2, I guess something is wrong around there.
msg259956 - (view) Author: Tamás Bence Gedai (beng94) * Date: 2016-02-09 22:14
I made a patch, that solves this issue.

The problem was that there wasn't any Sunday (%w = 0) on the 0th week in 2015. 2015 started on Thursday, therefore the first Sunday was on 2014.12.28.

julian variable is used to set the tm_yday, which was a minus value, as the given date was not in the same year.
msg260168 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-02-12 10:01
Could you please add tests?
msg260351 - (view) Author: Tamás Bence Gedai (beng94) * Date: 2016-02-16 07:50
Actually there are already test cases, but they test for the wrong behaviour. The very same example is tested there, but the test gives the expected result, so tm_yday = -3. My implementation returns 362, which looks more reasonable. So currently with my patch the test fails.

See the tests here: https://github.com/python/cpython/blob/master/Lib/test/test_strptime.py#L523
msg260353 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-02-16 09:02
Could you provide a patch? See also my comment on Rietveld (the "review" link).
msg260360 - (view) Author: Tamás Bence Gedai (beng94) * Date: 2016-02-16 12:11
I've added a new patch, it uses an other way to calculate the number of days in a given year. I updated the tests, so now it doesn't fail, I also added some extra test cases to test leap years.
msg261238 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-03-06 07:26
LGTM. Alexander, what would you say?
msg261642 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-03-12 08:53
New changeset f03da87a79fa by Serhiy Storchaka in branch '3.5':
Issue #23718: Fixed parsing time in week 0 before Jan 1.  Original patch by
https://hg.python.org/cpython/rev/f03da87a79fa

New changeset 4fb167ec3108 by Serhiy Storchaka in branch '2.7':
Issue #23718: Fixed parsing time in week 0 before Jan 1.  Original patch by
https://hg.python.org/cpython/rev/4fb167ec3108

New changeset a7093386efaf by Serhiy Storchaka in branch 'default':
Issue #23718: Fixed parsing time in week 0 before Jan 1.  Original patch by
https://hg.python.org/cpython/rev/a7093386efaf
msg261643 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-03-12 08:55
Thank you Tamás for your contribution.
History
Date User Action Args
2016-03-12 08:55:19serhiy.storchakasetstatus: open -> closed
resolution: fixed
messages: + msg261643

stage: commit review -> resolved
2016-03-12 08:53:58python-devsetnosy: + python-dev
messages: + msg261642
2016-03-06 07:26:32serhiy.storchakasetstage: patch review -> commit review
messages: + msg261238
versions: + Python 3.6, - Python 3.4
2016-03-06 07:22:00serhiy.storchakasetassignee: serhiy.storchaka
stage: test needed -> patch review
2016-02-16 12:11:47beng94setfiles: + julian_date_v1.patch

messages: + msg260360
2016-02-16 09:02:50serhiy.storchakasetmessages: + msg260353
2016-02-16 07:50:45beng94setmessages: + msg260351
2016-02-12 10:01:05serhiy.storchakasetmessages: + msg260168
stage: test needed
2016-02-12 05:21:45ned.deilysetnosy: + iaslan
2016-02-12 05:21:10ned.deilylinkissue26279 superseder
2016-02-09 22:14:14beng94setfiles: + julian_date.patch
keywords: + patch
messages: + msg259956
2016-02-06 23:17:59beng94setnosy: + beng94
messages: + msg259752
2015-03-20 11:30:32serhiy.storchakacreate