Skip to content

Fix fixed offset timezone conversion bug.#3269

Merged
adamreichold merged 1 commit intoPyO3:mainfrom
grantslatton:timezone-conversion-bugfix
Jul 4, 2023
Merged

Fix fixed offset timezone conversion bug.#3269
adamreichold merged 1 commit intoPyO3:mainfrom
grantslatton:timezone-conversion-bugfix

Conversation

@grantslatton
Copy link
Copy Markdown
Contributor

@grantslatton grantslatton commented Jun 24, 2023

Closes #3267

Comment thread src/conversions/chrono.rs Outdated
Comment thread src/conversions/chrono.rs Outdated
@adamreichold
Copy link
Copy Markdown
Member

Since we are going through a license change, please also have a loot at #3108

@adamreichold
Copy link
Copy Markdown
Member

Not sure what the Windows build failures are about. Is the Python installation missing the time zone database there?

@grantslatton
Copy link
Copy Markdown
Contributor Author

Not sure what the Windows build failures are about. Is the Python installation missing the time zone database there?

It's because Windows only supports times in 1970-2038 I believe, but the proptest is using a much larger range, I am fixing this now

@grantslatton
Copy link
Copy Markdown
Contributor Author

Hunting down some more bugs the more exhaustive proptest found. Found one in chrono: chronotope/chrono#1154

There is another one that results in the python vs rust datetimes being 1 second off when the time falls exactly on the daylight savings switchover. Unsure if pyo3 conversion bug (with the fold parameter) or just a discrepancy between python and chrono. Investigating further...

@pitdicker
Copy link
Copy Markdown

@grantslatton I am interested in the issues you may run into.

@grantslatton
Copy link
Copy Markdown
Contributor Author

grantslatton commented Jun 24, 2023

@grantslatton I am interested in the issues you may run into.

@pitdicker Does chrono have facilities for supporting ambiguous instants created at the end of daylight savings? i.e. https://peps.python.org/pep-0495/

@pitdicker
Copy link
Copy Markdown

Yes, you will want to look into methods that return a LocaleResult such as TimeZone::from_local_datetime.

Comment thread .vscode/settings.json Outdated
Comment thread proptest-regressions/conversions/chrono.txt Outdated
@grantslatton grantslatton force-pushed the timezone-conversion-bugfix branch from 0a8c978 to 139516c Compare June 25, 2023 17:22
@grantslatton
Copy link
Copy Markdown
Contributor Author

I am wondering if we should also fix #3266 in the same change, because this change will result in fold information being lost on FromPyObject, because PyO3's doesn't have a conversion out to DateTime<Tz> -- only DateTime<Utc> and DateTime<FixedOffset.

But doing this would require changing the IntoPy for DateTime<Tz: TimeZone> path to different impls: one for DateTime<Utc>, DateTime<FixedOffset>, DateTime<Local>, and DateTime<Tz>. This would be a breaking change that would break any downstream code that has defined their own custom TimeZone impl. There is probably no such code, as everyone is probably using timezones defined by chrono and chrono_tz.

I think such a change increases the correctness of this crate, because right now the conversion is lossy and loses daylight savings information present in chrono_tz::Tz locale timezones.

@adamreichold
Copy link
Copy Markdown
Member

This would be a breaking change that would break any downstream code that has defined their own custom TimeZone impl. There is probably no such code, as everyone is probably using timezones defined by chrono and chrono_tz.

This would mean the fix would also be limited to 0.20, the next release where breakage is possible. So I think the question is whether the side effects of losing the fold information is serious enough that one would say the backwards-compatible version of the fix cannot be used anyway?

Personally, I would be fine with try to fix this properly for 0.20 only because the chrono integration is still a relatively new feature of PyO3 and some churn seems expected.

@adamreichold
Copy link
Copy Markdown
Member

P.S.: You seem to have included two unrelated commits during your rebase.

@Psykopear
Copy link
Copy Markdown
Contributor

Ok, sorry for the delay. I've reviewed the issue and the PR, the bug is there, and this fixes it, nice catch.

I am wondering if we should also fix #3266 in the same change, because this change will result in fold information being lost on FromPyObject, because PyO3's doesn't have a conversion out to DateTime<Tz> -- only DateTime<Utc> and DateTime<FixedOffset>.

The problem with the chrono_tz integration IIRC, is that python<3.9 doesn't have the zoneinfo package in the standard library, and I'm not sure it's reasonable to implement the integration without that. So, unless there is an alternative solution I missed (that doesn't require adding a python dependency like backports.zoneinfo and/or tzdata), we'd probably need to put the chrono_tz integration under a separate feature (dependent on python>=3.9), and keep only the chrono one for python<3.9. The two features would also have to be mutually exclusive I think, because we can't implement the python traits for both chrono::Tz (the trait) and chrono_tz::Tz (the enum).

All that to say that it's probably ok to lose the fold info with just chrono (since we only handle fixedoffsets), and fix this for python>=3.9 in the chrono_tz integration.
Gating the new integration under a separate feature will also avoid breaking code that uses the current one, because you'd need to enable the chrono_tz feature.

Copy link
Copy Markdown
Member

@adamreichold adamreichold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grantslatton @Psykopear Ok, you to summarize my understanding: We take as it is and it fixes #3267 but #3266 will need a more involved approach which might even use an independent code path. Do you both agree with this?

@grantslatton
Copy link
Copy Markdown
Contributor Author

@grantslatton @Psykopear Ok, you to summarize my understanding: We take as it is and it fixes #3267 but #3266 will need a more involved approach which might even use an independent code path. Do you both agree with this?

Yes this is right

@adamreichold adamreichold added this pull request to the merge queue Jul 4, 2023
Merged via the queue into PyO3:main with commit 54ab909 Jul 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PyO3 incorrectly converts local to UTC times on FixedOffset conversion

4 participants