Skip to content

bpo-32497: let datetime.strptime interpret tzname#5106

Closed
akeeman wants to merge 10 commits into
python:masterfrom
akeeman:add-tzname-interpreter-to-strptime
Closed

bpo-32497: let datetime.strptime interpret tzname#5106
akeeman wants to merge 10 commits into
python:masterfrom
akeeman:add-tzname-interpreter-to-strptime

Conversation

@akeeman

@akeeman akeeman commented Jan 5, 2018

Copy link
Copy Markdown

Consider the following:

tz_naive_object = datetime.strptime("2018-01-05 13:10:00 CET", "%Y-%m-%d %H:%M:%S %Z")

Python's standard library is not capable of converting the timezone name CET to a tzinfo object. Therefore the case made above returns a timezone naive datetime object.

I propose to add an extra optional argument to _strptime.py's _strptime_datetime function, and to datetime.strptime: infos:Union[None, Mapping, Callable[[datetime, str],Optional[tzinfo]]]=None. This parameter can be set with a function that accepts the timezone name and returns a tzinfo object or None. None will mean that a timezone naive object will be created.

Usage:

tz_aware_object = datetime.strptime("2018-01-05 13:10:00 CET", "%Y-%m-%d %H:%M:%S %Z", {"CET": timezone(timedelta(hours=1))})

Note that I did not found the location to add tests yet. Can someone point it out to me?

https://bugs.python.org/issue32497

@the-knights-who-say-ni

Copy link
Copy Markdown

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately our records indicate you have not signed the CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

Thanks again to your contribution and we look forward to looking at it!

@pganssle

pganssle commented Jan 5, 2018

Copy link
Copy Markdown
Member

@akeeman I'll note that your example uses pytz.timezone, which will generally give the wrong answer when used (though this is entirely the fault of pytz for using a non-standard interface and very little can be done about it).

@pganssle

pganssle commented Jan 5, 2018

Copy link
Copy Markdown
Member

Tests go in Lib/test/datetimetester.py.

@csabella

Copy link
Copy Markdown
Contributor

It seems that this pull request might be abandoned. @pganssle, is this change something you think should be pursued in light of the other time zone changes you have planned? Thanks!

@pganssle

Copy link
Copy Markdown
Member

@csabella The new time zone support doesn't really change things, because the stuff you would parse with %Z is not a unique representation of any sort of time zone anyway, so there's nothing automagical we could do that would just return a standard library time zone.

I went into considerably more detail on the bpo issue about the possible options for this interface. I don't particularly like the one that @akeeman has chosen, but it's close enough to one that I'd accept as a compromise 😉.

If this or any other PR were to succeed, though, it would need:

  1. Tests (and probably pretty extensive ones, since parsing is tricky)
  2. To drop the reference to pytz, which would do the wrong thing and be misleading anyway.
  3. More extensive documentation in the datetime documentation about how to use this.

That said, regardless of any criticisms I have about the interface, I appreciate that @akeeman took the time to bring up this issue and to take an initial crack at the implementation, so thank you Arjan!

@csabella

Copy link
Copy Markdown
Contributor

@pganssle, thank you for your response. @akeeman, please let us know if you are interested in pursuing this pull request by applying the changes that Paul requested and by rebasing to resolve the merge conflicts. If you are no longer interested in this, then I'll close the PR to allow someone else to attempt it. Thanks!

@akeeman

akeeman commented May 19, 2019

Copy link
Copy Markdown
Author

@pganssle Thanks for the comment. I hope that there are better ways to do it too, but mostly wanted to start a discussion and have some ideas going. I'll read your linked issue soon. I'd like the best implementation, and that doesn't necessarily have to be this one. (@csabella "[...] then I'll close the PR to allow someone else to attempt it." -> if someone has interest to do it, you can make an attempt right now if you ask me. Don't hesitate to move this pr aside if there's a better one.)

As for this pr; The given points are clearly valid, and should be implemented. I'll try to make some time soon.

@akeeman

akeeman commented May 20, 2019

Copy link
Copy Markdown
Author

After reading the bpo issue, can I say that you, @pganssle, would like to see the arg I've called tzname_to_tzinfo to accept both a mapping of tzstr -> tz and a callable like handle_tzinfo(dt, tzstr)? Of course we could rename tzname_to_tzinfo to the much shorter tzinfos too...

@akeeman

akeeman commented May 22, 2019

Copy link
Copy Markdown
Author

Changed things to

datetime.strptime("2019-05-01 00:00:00 UTC", "%Y-%m-%d %H:%M:%S %Z", infos)

where infos is either a mapping, or a callable

infos = {"UTC": datetime.timezone(datetime.timedelta(hours=0))}
# or
def infos(dt: datetime.datetime, tzname: str) -> datetime.timezone:
    # some spaghetti here

(I still have to add tests)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants