Skip to content

Using datetime.datetime.utcnow().timestamp() in Python3.6.0 can't get correct UTC timestamp. #77474

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

Closed
HanShaowen mannequin opened this issue Apr 17, 2018 · 10 comments
Closed
Labels
extension-modules C modules in the Modules dir type-bug An unexpected behavior, bug, or error

Comments

@HanShaowen
Copy link
Mannequin

HanShaowen mannequin commented Apr 17, 2018

BPO 33293
Nosy @tim-one, @ned-deily

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 = <Date 2018-04-17.20:50:45.548>
created_at = <Date 2018-04-17.05:20:37.481>
labels = ['extension-modules', 'type-bug', 'invalid']
title = "Using datetime.datetime.utcnow().timestamp() in Python3.6.0 can't get correct UTC timestamp."
updated_at = <Date 2018-04-18.03:27:51.512>
user = 'https://bugs.python.org/HanShaowen'

bugs.python.org fields:

activity = <Date 2018-04-18.03:27:51.512>
actor = 'Han Shaowen'
assignee = 'none'
closed = True
closed_date = <Date 2018-04-17.20:50:45.548>
closer = 'ned.deily'
components = ['Extension Modules']
creation = <Date 2018-04-17.05:20:37.481>
creator = 'Han Shaowen'
dependencies = []
files = []
hgrepos = []
issue_num = 33293
keywords = []
message_count = 10.0
messages = ['315377', '315413', '315414', '315415', '315418', '315419', '315421', '315433', '315434', '315435']
nosy_count = 3.0
nosy_names = ['tim.peters', 'ned.deily', 'Han Shaowen']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue33293'
versions = ['Python 3.6']

@HanShaowen
Copy link
Mannequin Author

HanShaowen mannequin commented Apr 17, 2018

What I am talking is like:

Python 3.6.0 (default, Feb 28 2018, 15:41:04)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> from datetime import datetime
>>> time.time()
1523942154.3787892
>>> datetime.now().timestamp()
1523942165.202865
>>> datetime.utcnow().timestamp()
1523913372.362377

Apparently, datetime.now().timestamp() give me right unix timestamp while utcnow().timestamp() doesn't.

Fellas what do you think about this?

@HanShaowen HanShaowen mannequin added extension-modules C modules in the Modules dir type-bug An unexpected behavior, bug, or error labels Apr 17, 2018
@brettcannon
Copy link
Member

Are you seeing the same issue on Python 3.6.5?

@brettcannon
Copy link
Member

And we do have women on the team, so please minimize the "fellas" comments.

@ned-deily
Copy link
Member

I am not sure I understand what behavior you are expecting. But datetime.now() is documented as returning "the current local date and time" (assuming no tx= argument is provided) while datetime.utcnow() returns "the current UTC date and time". So I would expect the two to provide a similar value only if your system/process local time zone is set to UTC. I'm guessing the time zone in effect when your examples were run was 8 hours ahead of UTC:

>>> (1523942165.202865 - 1523913372.362377) / (60*60)
7.998011246654722

https://docs.python.org/3/library/datetime.html

@tim-one
Copy link
Member

tim-one commented Apr 17, 2018

I agree this isn't a bug (and it was right to close it). I expect the OP is confused about what the .timestamp() method does, though. This note in the docs directly address what happens in their problematic datetime.utcnow().timestamp() case:

"""
Note There is no method to obtain the POSIX timestamp directly from a naive datetime instance representing UTC time. If your application uses this convention and your system timezone is not set to UTC, you can obtain the POSIX timestamp by supplying tzinfo=timezone.utc:

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

or by calculating the timestamp directly:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
"""

@ned-deily
Copy link
Member

Tim, do you think the docs should be changed and, if so, which sections? If you dictate, I'll type!

@tim-one
Copy link
Member

tim-one commented Apr 17, 2018

Ned, I think this one is more the case that the OP didn't read the docs ;-)

That said, there's a level of complexity here that seemingly can't be reduced: the distinctions between the datetime and time modules' views of the world, and between datetime's notions of aware and naive datetime objects. Those are general distinctions that apply all over the place, not just in a method or two's docs.

Given that those are understood, the OP's results "are obvious". But it takes some work for users to get to that point, and best I can tell the current docs have been successful at helping users get there - but they do have to do the work of reading them thoughtfully.

@HanShaowen
Copy link
Mannequin Author

HanShaowen mannequin commented Apr 18, 2018

Guys, what I said is the doc in help(datetime.timestamp) is 'Return POSIX timestamp as float.' So I assumed it is irrelevant to time zone, considering POSIX timestamp's definition. If it is then datetime.now and datetime.utcnow should return the same timestamp. But datetime.now().timestamp return a correct timestamp which I checked in the website https://www.unixtimestamp.com/ but datetime.utcnow().timestamp did not.

:)

@tim-one
Copy link
Member

tim-one commented Apr 18, 2018

docstrings give brief statements intended to jog your memory; they're not intended to be comprehensive docs. Read the actual documentation and see whether you're still confused. When you "assumed it is irrelevant to time zone", that was your _assumption_, which the actual docs would have clarified.

The whole story simply can't be told here without docs that make the distinction between "naive" and "aware" datetime objects, and the connection to what your platform's C mktime() function does about your local time zone. The brief docstring is correct that a POSIX timestamp is returned (a count of seconds from the UTC epoch). But how that relates to the datetime object requires reading the docs, not blind guessing ;-)

@HanShaowen
Copy link
Mannequin Author

HanShaowen mannequin commented Apr 18, 2018

Hohoho, I found the full-version doc. This issue over. Thanks Tim, Ned and Brett. And sorry about something improper I said, I respect female Pythonista.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension-modules C modules in the Modules dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants