[issue26460] datetime.strptime without a year fails on Feb 29

2020-03-03 Thread Nick Moore


Nick Moore  added the comment:

It's kind of funny that there's already consideration of this in 
_strptime._strptime(), which returns a tuple used by 
datetime.datetime.strptime() to construct the new datetime.
Search for `leap_year_fix`.

I think the concern though is if we changed the default year that might 
possibly break someone's existing code: thus my suggestion to allow the 
programmer to explicitly change the default.

However, I can also see that if their code is parsing dates in this way it is 
already wrong, and that if we're causing users pain now when they upgrade 
Python we're at least saving them pain at 2024-02-29 00:00:01.

Taking that approach, perhaps parsing dates with no year should just throw an 
exception, forcing the programmer to do it right the first time.  In this case 
though, I'd rather have a "year" kwarg to prevent the programmer having to do 
horrible string hacks like my code currently does.

I'm not sure: is it useful for me to produce a PR so we have something specific 
to consider?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2020-03-03 Thread Gerard C Weatherby


Gerard C Weatherby  added the comment:

Yes, code that has been working for my organization the past two years just 
broke this weekend.

Meaning depends on context. The straightforward solution is that if no year is 
specified, the return value should default to the current year.

--
nosy: +gera...@alum.mit.edu

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2020-03-02 Thread Alexander Belopolsky


Alexander Belopolsky  added the comment:

> On Mar 2, 2020, at 6:33 PM, Gregory P. Smith  wrote:
> 
> Change that default to any old year with a leap year (1904?)

In the 21st century, the year 2000 default makes much more sense than 1900. 
Luckily 2000 is also a leap year.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2020-03-02 Thread Gregory P. Smith


Gregory P. Smith  added the comment:

I _doubt_ there is code expecting the default year when unspecified to actually 
be 1900.

Change that default to any old year with a leap year (1904?) and it'll still 
(a) stand out as a special year that can be looked up should it wind up being 
_used_ as the year in code somewhere and (b) not fail every four years for 
people just parsing to extract Month + Day values.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2020-03-02 Thread Nick Moore


Nick Moore  added the comment:

Not disagreeing with you that "%b %d" timestamps with no "%Y" are excerable, 
but they're fairly common in the *nix world unfortunately.

People need to parse them, and the simple and obvious way to do this breaks 
every four years.

I like the idea of having a warning for not including %Y *and* not setting a 
default_year kwarg though.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2020-03-02 Thread Paul Ganssle


Paul Ganssle  added the comment:

I don't think adding a default_year parameter is the right solution here.

The actual problem is that `time.strptime`, and by extension 
`datetime.strptime` has a strange and confusing interface. What should happen 
is either that `year` is set to None or some other marker of a missing value or 
datetime.strptime should raise an exception when it's being asked to construct 
something that does not contain a year.

Since there is no concept of a partial datetime, I think our best option would 
be to throw an exception, except that this has been baked into the library for 
ages and would start to throw exceptions even when the person has correctly 
handled the Feb 29th case.

I think one possible "solution" to this would be to raise a warning any time 
someone tries to use `datetime.strptime` without requesting a year to warn them 
that the thing they're doing only exists for backwards compatibility reasons. 
We could possibly eventually make that an exception, but I'm not sure it's 
totally worth a break in backwards compatibility when a warning should put 
people on notice.

--
nosy: +p-ganssle

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2020-03-01 Thread Nick Moore


Nick Moore  added the comment:

I suspect this is going to come up about this time of every leap year :-/

The workaround is prepending "%Y " to the pattern and eg: "2020 " to the date 
string, but that's not very nice.

Would adding a kwarg "default_year" be an acceptable solution?
I can't think of any other situation other than leap years when this is going 
to come up.  If both "default_year" and "%Y" are present throw an exception 
(maybe therefore just call the kwarg "year")

In the weird case where you want to do date maths involving the month as well, 
you can always use a safe choice like "default_year=2020" and then fix the year 
up afterwards:

```
dt = datetime.strptime(date_str, "%b %d", default_year=2020)
dt = dt.replace(year=2021 if dt.month > 6 else 2022)
```

--
nosy: +nickzoic
versions: +Python 3.7, Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2019-05-21 Thread Karthikeyan Singaravelan


Karthikeyan Singaravelan  added the comment:

See also issue19376. This behavior is now documented with 
https://github.com/python/cpython/commit/56027ccd6b9dab4a090e4fef8574933fb9a36ff2

--
nosy: +xtreak

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2016-03-02 Thread Andrej Antonov

Changes by Andrej Antonov :


--
nosy: +polymorphm

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2016-02-29 Thread Gregory P. Smith

Gregory P. Smith added the comment:

time.strptime() is "working" (not raising an exception) as it appears not to 
validate the day of the month when a year is not specified, yet the return 
value from either of these APIs is a date which has no concept of an ambiguous 
year.

## Via the admittedly old Python 2.7.6 from Ubuntu 14.04: ##
# 1900 was not a leap year as it is not divisible by 400.
>>> time.strptime("1900 Feb 29", "%Y %b %d")
ValueError: day is out of range for month
>>> 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)

So what should the validation behavior be?

>>> datetime.datetime.strptime("Feb 29", "%b %d")
ValueError: day is out of range for month
>>> datetime.datetime.strptime("2016 Feb 29", "%Y %b %d")
datetime.datetime(2016, 2, 29, 0, 0)
>>> datetime.datetime.strptime("1900 Feb 29", "%Y %b %d")
ValueError: day is out of range for month
>>> datetime.datetime(year=1900, month=2, day=29)
ValueError: day is out of range for month

datetime objects cannot be constructed with the invalid date (as the 
time.strptime return value allows).

Changing the API to assume the current year or a +/- 6 months from "now" when 
no year is parsed is likely to break existing code.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2016-02-29 Thread Alexander Belopolsky

Alexander Belopolsky added the comment:

> Python's time.strptime() behavior is consistent with that of glibc 2.19

Gregory,

I believe OP is complaining about the way datetime.datetime.strptime() behaves, 
not time.strptime() which is mentioned as (preferred?) alternative.


See msg261015  in issue 14157 for context.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2016-02-29 Thread Alexander Belopolsky

Alexander Belopolsky added the comment:

This is not no more bug than

>>> from datetime import *
>>> datetime.strptime('0228', '%m%d')
datetime.datetime(1900, 2, 28, 0, 0)

Naturally, as long as datetime.strptime('0228', '%m%d') is the same as 
datetime.strptime('19000228', '%Y%m%d'), datetime.strptime('0229', '%m%d') 
should raise a ValueError as long as datetime.strptime('19000229', '%m%d') does.

The only improvement, I can think of in this situation is to point the user to 
time.strptime() in the error message.  The time.strptime method works just fine 
in the recent versions (see issue 14157.)

>>> time.strptime('0229', '%m%d')[1:3]
(2, 29)

--
nosy: +belopolsky
type: behavior -> enhancement
versions:  -Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2016-02-29 Thread Gregory P. Smith

Gregory P. Smith added the comment:

Python's time.strptime() behavior is consistent with that of glibc 2.19:

=== strptime_c.c ===
#define _XOPEN_SOURCE
#include 
#include 
#include 
#include 

int
main(void)
{
  struct tm tm;
  char buf[255];

  memset(, 0, sizeof(struct tm));
  strptime("Feb 29", "%b %d", );
  strftime(buf, sizeof(buf), "%d %b %Y %H:%M", );
  puts(buf);
  exit(EXIT_SUCCESS);
}
===

$ gcc strptime_c.c 
$ ./a.out
29 Feb 1900 00:00


I'm not saying that the behavior is a good API, but given the unfortunate API 
at hand, parsing a date without specifying what year it is using strptime is a 
bad idea.

--
nosy: +gregory.p.smith

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26460] datetime.strptime without a year fails on Feb 29

2016-02-29 Thread Sriram Rajagopalan

New submission from Sriram Rajagopalan:

$ 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 "", line 1, in 
  File "/usr/lib/python3.5/_strptime.py", line 511, in _strptime_datetime
return cls(*args)
ValueError: day is out of range for month

The same issue is seen in all versions of Python

--
components: Library (Lib)
messages: 261014
nosy: Sriram Rajagopalan
priority: normal
severity: normal
status: open
title: datetime.strptime without a year fails on Feb 29
type: behavior
versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, Python 3.6

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com