Skip to content

Inconsistency between datetime.now() and datetime.fromtimestamp(time.time(), None) #88994

Closed
@Miksus

Description

@Miksus
mannequin
BPO 44831
Nosy @rhettinger, @pfmoore, @abalkin, @vstinner, @larryhastings, @tjguk, @stevendaprano, @zware, @zooba, @pganssle, @Miksus

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 2021-08-04.17:49:51.110>
labels = ['type-bug', 'library', 'OS-windows', '3.11']
title = 'Inconsistency between datetime.now() and datetime.fromtimestamp(time.time(), None)'
updated_at = <Date 2021-10-04.08:57:15.356>
user = 'https://github.com/Miksus'

bugs.python.org fields:

activity = <Date 2021-10-04.08:57:15.356>
actor = 'vstinner'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)', 'Windows']
creation = <Date 2021-08-04.17:49:51.110>
creator = 'Miksus'
dependencies = []
files = []
hgrepos = []
issue_num = 44831
keywords = []
message_count = 10.0
messages = ['398919', '398922', '399068', '399070', '399090', '399096', '399097', '403063', '403124', '403125']
nosy_count = 11.0
nosy_names = ['rhettinger', 'paul.moore', 'belopolsky', 'vstinner', 'larry', 'tim.golden', 'steven.daprano', 'zach.ware', 'steve.dower', 'p-ganssle', 'Miksus']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue44831'
versions = ['Python 3.11']

Linked PRs

Activity

Miksus

Miksus commented on Aug 4, 2021

@Miksus
MannequinAuthor

I am trying to measure time twice and the second measurement gives a time that is 1 microsecond before the first measurement about half of the time.

My experiment in short:
---------------------------------------------------

import time, datetime
start = time.time()
end = datetime.datetime.now()

start = datetime.datetime.fromtimestamp(start, None)
assert end >= start # fails about half the time.

The problem is somewhat interesting. This does not fail:
---------------------------------------------------

import time, datetime
start = time.time()
end = time.time()

start = datetime.datetime.fromtimestamp(start, None)
end = datetime.datetime.fromtimestamp(end, None)
assert end >= start

And neither does this:
---------------------------------------------------

import datetime
start = datetime.datetime.now()
end = datetime.datetime.now()
assert end >= start

And it seems datetime.datetime.now() works the same way as to how I handled the "start" time in my first experiment:
https://github.com/python/cpython/blob/3.6/Lib/datetime.py#L1514
and therefore the issue seems to be under the hood.

I have tested this on two Windows 10 machines (Python 3.6 & 3.8) in which cases this occurred. This did not happen on Raspberry Pi OS using Python 3.7.

In short:

  • The time module imported in datetime.datetime.now() seems to measure time slightly differently than the time module imported by a Python user.
  • This seems to be Windows specific.

My actual application has some code in between the measurements suffering from the same problem thus this is not an issue affecting only toy examples.

Miksus

Miksus commented on Aug 4, 2021

@Miksus
MannequinAuthor

I accidentially posted Python 3.6 link to the declaration of datetime.datetime.now() but this has been unchanged:

def now(cls, tz=None):

The actual piece of code as of now:
...
import time as _time
...
@classmethod
def now(cls, tz=None):
"Construct a datetime from time.time() and optional time zone info."
t = _time.time()
return cls.fromtimestamp(t, tz)

stevendaprano

stevendaprano commented on Aug 6, 2021

@stevendaprano
Member

Confirmed on Windows with Python 3.9.6.

added
3.9only security fixes
type-bugAn unexpected behavior, bug, or error
on Aug 6, 2021
stevendaprano

stevendaprano commented on Aug 6, 2021

@stevendaprano
Member

I've replicated this under Linux as well.

def test():
    start = time.time()
    end = datetime.datetime.now()
    start = datetime.datetime.fromtimestamp(start, None)
    assert end >= start

Then run it in a loop:

>>> for i in range(10000000):
...     test()
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 5, in test
AssertionError
>>> i
22

So while it is not as frequent as on Windows, it does occur on Linux as well.

abalkin

abalkin commented on Aug 6, 2021

@abalkin
Member

Can someone try to replicate this while disabling the C acceleration:

import sys
sys.modules[‘_datetime’] = None

(Before any other imports.)

If anything, this is likely to be a problem with the C implementation.

25 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Inconsistency between datetime.now() and datetime.fromtimestamp(time.time(), None) · Issue #88994 · python/cpython

      Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

      Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant