Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

datetime.max conversion #91012

Open
jorisgeysens mannequin opened this issue Feb 25, 2022 · 8 comments
Open

datetime.max conversion #91012

jorisgeysens mannequin opened this issue Feb 25, 2022 · 8 comments
Labels
3.9 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@jorisgeysens
Copy link
Mannequin

jorisgeysens mannequin commented Feb 25, 2022

BPO 46856
Nosy @ericvsmith

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2022-02-25.16:10:01.560>
labels = ['type-bug', 'library', '3.9']
title = 'datetime.max conversion'
updated_at = <Date 2022-03-01.15:47:18.405>
user = 'https://bugs.python.org/jorisgeysens'

bugs.python.org fields:

activity = <Date 2022-03-01.15:47:18.405>
actor = 'joris.geysens'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2022-02-25.16:10:01.560>
creator = 'joris.geysens'
dependencies = []
files = []
hgrepos = []
issue_num = 46856
keywords = []
message_count = 6.0
messages = ['414013', '414023', '414032', '414043', '414044', '414275']
nosy_count = 2.0
nosy_names = ['eric.smith', 'joris.geysens']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue46856'
versions = ['Python 3.9']

@jorisgeysens
Copy link
Mannequin Author

jorisgeysens mannequin commented Feb 25, 2022

Reading the documentation, I don't understand how this is not possible :

# get the max utc timestamp
ts = datetime.max.replace(tzinfo=timezone.utc).timestamp()

# similarly 
ts2 = datetime(9999, 12, 31, 23, 59, 59, 999999, tzinfo=timezone.utc).timestamp()

# timestamp value 253402300800 seems correct
# converting back to timestamp is impossible, these all fail :

dt = datetime.fromtimestamp(ts, tz=timezone.utc)
dt = datetime.utcfromtimestamp(ts)

It should be possible to get a datetime back from the initially converted timestamp, no?

@jorisgeysens jorisgeysens mannequin added 3.9 only security fixes type-bug An unexpected behavior, bug, or error labels Feb 25, 2022
@ericvsmith
Copy link
Member

Please show us how they fail.

@jorisgeysens
Copy link
Mannequin Author

jorisgeysens mannequin commented Feb 25, 2022

a ValueError is raised :

ValueError: year 10000 is out of range

on

dt = datetime.fromtimestamp(ts, tz=timezone.utc)

or

dt = datetime.utcfromtimestamp(ts)

@jorisgeysens
Copy link
Mannequin Author

jorisgeysens mannequin commented Feb 25, 2022

I see this in the python source code being tested (datetimetester.py), so I guess it is a rounding problem :

# maximum timestamp: set seconds to zero to avoid rounding issues
        max_dt = self.theclass.max.replace(tzinfo=timezone.utc,
                                           second=0, microsecond=0)
        max_ts = max_dt.timestamp()
        # date 9999-12-31 23:59:00+00:00: timestamp 253402300740
        self.assertEqual(self.theclass.fromtimestamp(max_ts, tz=timezone.utc),
                         max_dt)

@jorisgeysens jorisgeysens mannequin added stdlib Python modules in the Lib dir labels Feb 25, 2022
@ericvsmith
Copy link
Member

Probably so. You could step through the code to make sure that's what's going on.

@jorisgeysens
Copy link
Mannequin Author

jorisgeysens mannequin commented Mar 1, 2022

I looked at this a bit more in detail.
What happens it the following, starting in the datetime fromtimestamp fragment :

converter = _time.gmtime if utc else _time.localtime
y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)

That will call the system gmtime_r(), which indeed returns Sat Jan 1 00:00:00 10000

I have not looked at the cpp implementation for that method and I am not sure if this is something that can be improved.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@psarka
Copy link

psarka commented Apr 15, 2022

The min range of the datetime is also affected:

>>> import datetime as dt
>>> dt.datetime.min.timestamp()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year 0 is out of range

@pganssle
Copy link
Member

I have noticed that the behavior of datetime.min.timestamp, datetime.max.timestamp and datetime.fromtimestamp that would result in values close to the minimum and maximum are failing in certain locales basically because of bugs in our code. I'm going to call this the issue for tracking that.

In reality, this does not matter, because timestamps that far away from the current date are essentially meaningless, but we should probably have well-defined limits so that people can reason well enough about their code. I propose that on all platforms that support it (e.g. not Windows):

  1. datetime.fromtimestamp() and datetime.utcfromtimestamp() should always work if the timestamp represents a datetime that can be represented by the datetime.class.
  2. datetime.timestamp() should never error out because some intermediate calculation hits some datetime outside the allowed range.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.9 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
Development

No branches or pull requests

3 participants