This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2012年02月29日 11:57 by Martin.Morrison, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| strptime-on-leap-years.diff | hynek, 2012年04月21日 17:09 | review | ||
| strptime-restore-1900.diff | hynek, 2012年05月14日 17:28 | review | ||
| strptime-restore-1900-v2.diff | hynek, 2012年05月14日 17:35 | review | ||
| Messages (21) | |||
|---|---|---|---|
| msg154621 - (view) | Author: Martin Morrison (Martin.Morrison) | Date: 2012年02月29日 11:57 | |
time.strptime without a year fails on Feb 29 with:
>>> time.strptime("Feb 29", "%b %d")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/_strptime.py", line 454, in _strptime_time
return _strptime(data_string, format)[0]
File "/usr/lib/python2.6/_strptime.py", line 440, in _strptime
datetime_date(year, 1, 1).toordinal() + 1
ValueError: day is out of range for month
This is due to the use of "1900" as the default year when parsing. It would be nice to have an optional "defaults" keyword argument to the strptime function that can be used to override the defaults, thus allowing leap year dates to be parsed without specifying the date.
(Note: the code in question attempted to set the year *after* the parse so that ultimately there is a valid struct_time, but since the parse never succeeds, this can't work).
|
|||
| msg154642 - (view) | Author: Alexander Belopolsky (belopolsky) * (Python committer) | Date: 2012年02月29日 15:48 | |
This strikes me as an implementation artifact. There is no reason for time.strptime() to validate date triplets. Applications that require valid dates can use datetime.strptime(). I suggest changing time.strptime() specification to match POSIX strptime(). My understanding is that POSIX only requires field by field range checking (%d range 01 to 31, %m range 01 to 12) and not full structure validation. This would be consistent with the way leap seconds are currently treated:
>>> time.strptime('60', '%S')[5]
60
|
|||
| msg154659 - (view) | Author: Shawn (swalker) | Date: 2012年02月29日 18:54 | |
I'm seeing this when a year *is* specified with Python 2.6 and 2.7:
import time
time.strptime("20090229T184823Z", "%Y%m%dT%H%M%SZ")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/_strptime.py", line 454, in _strptime_time
return _strptime(data_string, format)[0]
File "/usr/lib/python2.6/_strptime.py", line 440, in _strptime
datetime_date(year, 1, 1).toordinal() + 1
ValueError: day is out of range for month
import datetime
datetime.datetime.strptime("20090229T184823Z", "%Y%m%dT%H%M%SZ")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/_strptime.py", line 440, in _strptime
datetime_date(year, 1, 1).toordinal() + 1
ValueError: day is out of range for month
|
|||
| msg154661 - (view) | Author: Shawn (swalker) | Date: 2012年02月29日 19:05 | |
I'm an idiot; nevermind my comment. The original date was bogus. |
|||
| msg158207 - (view) | Author: Hynek Schlawack (hynek) * (Python committer) | Date: 2012年04月13日 12:46 | |
The point isn’t that time.strptime validates dates but that it uses datetime internally: julian = datetime_date(year, month, day).toordinal() - \ datetime_date(year, 1, 1).toordinal() + 1 Is it worth to reimplement this functionality? It strikes easier to me to just use a different year if year is undefined and date == Feb 29. |
|||
| msg158926 - (view) | Author: Hynek Schlawack (hynek) * (Python committer) | Date: 2012年04月21日 17:09 | |
I gave it a shot, doesn’t look like a hack to me, what do you think? |
|||
| msg159692 - (view) | Author: Alexander Belopolsky (belopolsky) * (Python committer) | Date: 2012年04月30日 13:40 | |
This is a bit of a hack, but seems to get the work done. Does anyone have any objections to committing? |
|||
| msg159736 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2012年04月30日 23:06 | |
Fine with me. |
|||
| msg160358 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2012年05月10日 18:20 | |
New changeset f2ea7505c0d7 by Antoine Pitrou in branch '3.2': Issue #14157: Fix time.strptime failing without a year on February 29th. http://hg.python.org/cpython/rev/f2ea7505c0d7 New changeset a5a254e8a291 by Antoine Pitrou in branch 'default': Issue #14157: Fix time.strptime failing without a year on February 29th. http://hg.python.org/cpython/rev/a5a254e8a291 |
|||
| msg160359 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2012年05月10日 18:23 | |
New changeset 69d407b016c1 by Antoine Pitrou in branch '2.7': Issue #14157: Fix time.strptime failing without a year on February 29th. http://hg.python.org/cpython/rev/69d407b016c1 |
|||
| msg160360 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2012年05月10日 18:24 | |
Patch committed and pushed, thank you! |
|||
| msg160637 - (view) | Author: Martin Morrison (Martin.Morrison) | Date: 2012年05月14日 16:50 | |
This solution has some very undesirable properties - namely that Mar 1st is now less than Feb 29th! It seems like the correct follow up fix would be to adjust the date of the returned struct_time back to 1900. The struct_time object doesn't have the validation issue, so this works fine. This pair of fixes then nicely circumvents the intermediate datetime object's checking, while providing a consistent end result. |
|||
| msg160638 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2012年05月14日 16:54 | |
That's a good point, thank you. Hynek, do you want to provide a new patch? |
|||
| msg160639 - (view) | Author: Hynek Schlawack (hynek) * (Python committer) | Date: 2012年05月14日 17:00 | |
On it. I wonder whether it causes trouble that we return an invalid time_struct down the road? |
|||
| msg160644 - (view) | Author: Hynek Schlawack (hynek) * (Python committer) | Date: 2012年05月14日 17:28 | |
I have added a restoration including a short explanation + a regression test. |
|||
| msg160646 - (view) | Author: Hynek Schlawack (hynek) * (Python committer) | Date: 2012年05月14日 17:35 | |
Small adjustments to the test as discussed in IRC. |
|||
| msg160648 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2012年05月14日 17:50 | |
New changeset 83598eb0d761 by Antoine Pitrou in branch '3.2': Followup to issue #14157: respect the relative ordering of values produced by time.strptime(). http://hg.python.org/cpython/rev/83598eb0d761 New changeset d1c0b57aeb1b by Antoine Pitrou in branch 'default': Followup to issue #14157: respect the relative ordering of values produced by time.strptime(). http://hg.python.org/cpython/rev/d1c0b57aeb1b New changeset cbc9dc1c977e by Antoine Pitrou in branch '2.7': Followup to issue #14157: respect the relative ordering of values produced by time.strptime(). http://hg.python.org/cpython/rev/cbc9dc1c977e |
|||
| msg160649 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2012年05月14日 17:51 | |
Thanks, this should be fine now. |
|||
| msg261002 - (view) | Author: Andrei Antonov (polymorphm) * | Date: 2016年02月29日 10:32 | |
$ python
Python 3.5.1 (default, Dec 7 2015, 12:58:09)
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>>
>>> import time
>>>
>>> time.strptime("Feb 29", "%b %d")
time.struct_time(tm_year=1900, tm_mon=2, tm_mday=29, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=60, tm_isdst=-1)
>>>
>>>
>>> import datetime
>>>
>>> datetime.datetime.strptime("Feb 29", "%b %d")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/_strptime.py", line 511, in _strptime_datetime
return cls(*args)
ValueError: day is out of range for month
|
|||
| msg261005 - (view) | Author: Sriram Rajagopalan (Sriram Rajagopalan) | Date: 2016年02月29日 11:45 | |
datetime.strptime() uses the return value of _strptime() [ which returns 1900 for 29th Feb without an year ] and eventually ends up calling datetime_new()->check_date_args() [ datetimemodule.c ] with 29th Feb 1900 and eventual failure. Should we enhance check_date_args to take a year_dont_care flag and validate the input year argument only if it is explicitly passed? |
|||
| msg261015 - (view) | Author: Sriram Rajagopalan (Sriram Rajagopalan) | Date: 2016年02月29日 18:04 | |
Opened issue 26460 for fixing the leap day bug in datetime.datetime.strptime() |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:27 | admin | set | github: 58365 |
| 2016年02月29日 18:04:45 | Sriram Rajagopalan | set | messages: + msg261015 |
| 2016年02月29日 11:45:24 | Sriram Rajagopalan | set | nosy:
+ Sriram Rajagopalan messages: + msg261005 |
| 2016年02月29日 10:32:27 | polymorphm | set | nosy:
+ polymorphm messages: + msg261002 |
| 2013年10月23日 16:42:07 | pconnell | set | nosy:
+ pconnell |
| 2012年05月14日 17:51:17 | pitrou | set | status: open -> closed resolution: fixed messages: + msg160649 stage: patch review -> resolved |
| 2012年05月14日 17:50:50 | python-dev | set | messages: + msg160648 |
| 2012年05月14日 17:35:04 | hynek | set | files:
+ strptime-restore-1900-v2.diff type: enhancement -> behavior messages: + msg160646 assignee: hynek resolution: fixed -> (no value) stage: resolved -> patch review |
| 2012年05月14日 17:28:40 | hynek | set | files:
+ strptime-restore-1900.diff messages: + msg160644 |
| 2012年05月14日 17:00:30 | hynek | set | messages: + msg160639 |
| 2012年05月14日 16:54:39 | pitrou | set | status: closed -> open messages: + msg160638 |
| 2012年05月14日 16:50:16 | Martin.Morrison | set | messages: + msg160637 |
| 2012年05月10日 18:24:16 | pitrou | set | status: open -> closed messages: + msg160360 assignee: belopolsky -> (no value) resolution: fixed stage: commit review -> resolved |
| 2012年05月10日 18:23:04 | python-dev | set | messages: + msg160359 |
| 2012年05月10日 18:20:56 | python-dev | set | nosy:
+ python-dev messages: + msg160358 |
| 2012年04月30日 23:06:29 | pitrou | set | nosy:
+ pitrou messages: + msg159736 stage: patch review -> commit review |
| 2012年04月30日 13:40:47 | belopolsky | set | messages: + msg159692 |
| 2012年04月30日 13:29:39 | Arfrever | set | nosy:
+ Arfrever |
| 2012年04月29日 15:41:01 | hynek | set | keywords:
+ needs review stage: needs patch -> patch review |
| 2012年04月21日 17:09:49 | hynek | set | files:
+ strptime-on-leap-years.diff keywords: + patch messages: + msg158926 |
| 2012年04月13日 12:46:46 | hynek | set | messages: + msg158207 |
| 2012年02月29日 19:05:44 | swalker | set | messages: + msg154661 |
| 2012年02月29日 18:54:24 | swalker | set | nosy:
+ swalker messages: + msg154659 |
| 2012年02月29日 15:48:41 | belopolsky | set | assignee: belopolsky type: behavior -> enhancement messages: + msg154642 stage: needs patch |
| 2012年02月29日 14:40:09 | pitrou | set | nosy:
+ belopolsky, vstinner, hynek versions: + Python 3.2, Python 3.3 |
| 2012年02月29日 11:57:47 | Martin.Morrison | create | |