41
datetime.utcnow()

This call is returning an incorrect datetime, delayed from UTC/GMT by 1 hour (check in: http://www.worldtimeserver.com/current_time_in_UTC.asp).

Is it working like it should be?

For example, it's returning, right now:

2015-02-17 23:58:44.761000.

Current UTC time is: 00:58, not 23:58

9
  • what's your timezone? Commented Feb 18, 2015 at 0:37
  • What does time.timezone say, and is it the right offset (in seconds) for your timezone? Commented Feb 18, 2015 at 0:42
  • 1
    It returns 2015-02-17 23:58:44.761000. Current UTC time is: 00:58, not 23:58. Commented Feb 18, 2015 at 0:59
  • 2
    make sure it is not "Clock time is off on dual boot" issue Commented Feb 18, 2015 at 1:00
  • 1
    Are the values returned by time.time(), time.gmtime(), GetSystemTimeAsFileTime() consistent with each other on your machine? Commented Feb 18, 2015 at 22:24

5 Answers 5

87

I know I'm five years late, but I had the same problem tonight. In my experience, the solution to the problem was to use the aware UTC datetime:

utc_dt_aware = datetime.datetime.now(datetime.timezone.utc)

If you google "utcnow() wrong" this is the first result you get, so I thought it would be good to answer anyway.

Sign up to request clarification or add additional context in comments.

Comments

15

datetime.utcnow() uses OS provided values.

datetime.utcnow() uses gettimeofday(2) or time.time() on Python 2 (and gmtime(3) to convert the result into broken-down time).

time.time() uses gettimeofday(2), ftime(3), time(2). Newer CPython versions may use clock_gettime(2), GetSystemTimeAsFileTime().

You could check the self-consistency as follows:

#!/usr/bin/env python
import time
from datetime import datetime, timedelta

print(datetime.utcnow())
print(datetime(1970, 1, 1) + timedelta(seconds=time.time()))
print(datetime(*time.gmtime()[:6]))

Here's (non-tested) code that calls GetSystemTimeAsFileTime() on Windows based on CPython source:

#!/usr/bin/env python
import ctypes.wintypes
from datetime import datetime, timedelta

def utcnow_microseconds():
    system_time = ctypes.wintypes.FILETIME()
    ctypes.windll.kernel32.GetSystemTimeAsFileTime(ctypes.byref(system_time))
    large = (system_time.dwHighDateTime << 32) + system_time.dwLowDateTime
    return large // 10 - 11644473600000000

print(datetime(1970, 1, 1) + timedelta(microseconds=utcnow_microseconds()))

Here's code that calls clock_gettime() on Python 2.

Comments

0

The utcnow is deprecated

Replace this

datetime.utcnow()

With this

from datetime import datetime, timezone

datetime.now(timezone.utc)

Comments

-8

Problem only occurs with utc time (Python3).

e.g. System time:

$ date

Wed Jul 15 10:44:26 BST 2015

Python time correct when using datetime.now():

>>> datetime.now()

datetime.datetime(2015, 7, 15, 10, 44, 30, 775840)

...But incorrect by one hour when using datetime.utcnow():

>>> datetime.utcnow()

datetime.datetime(2015, 7, 15, 9, 44, 32, 599823)

UTC's problem is it doesn't know my timezone.

You have to tell it, with the help of a timezone module called pytz:

>>> import pytz
>>> mytz = pytz.timezone('Europe/London')
>>> pytz.utc.localize(datetime.utcnow(), is_dst=None).astimezone(mytz)

datetime.datetime(2015, 7, 15, 11, 3, 43, 688681, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)

References:

pytz - Converting UTC and timezone to local time

https://opensourcehacker.com/2008/06/30/relativity-of-time-shortcomings-in-python-datetime-and-workaround/

http://sweemengs-tech-world.blogspot.co.uk/2010/05/get-correct-datetime-value-for-python.html

http://bugs.python.org/issue5094)

10 Comments

why do you think that utcnow() is incorrect? Unless your local timezone has zero utc offset; utc time will be different from the local time. Unrelated: you could use datetime.now(timezone), to get the current time in the given timezone. The references that you've provided are not good. For the first one; read my comments there.
BST has nonzero utc offset therefore it is expected that utcnow() returns datetime that is different from now(): "local time = utc time + utc offset"
wrong. utcnow() is the same around the world (+/- clock sync.). It does not matter what is your local timezone; utc time remains the same e.g., it is now 2015-07-16T23:41:30Z (UTC). If you run datetime.utcnow() on your computer then you should get similar time regardless of your timezone (if you are on a POSIX system; you could easily change your timezone using TZ envvar and see for yourself that utcnow() does not change (now() is likely to change if you change your local timezone). .utcnow() may jump by around 26 seconds if you use "right" timezone but it is another issue.
You have some incorrect preconceptions about utc. You should prefer working with utc in most cases (it is much easier than working with local time) e.g., Find if 24 hrs have passed between datetimes - Python. See, Daylight saving time and time zone best practices.
You seem to completely miss the point of using UTC. I'd go as far as to say you should always store UTC timestamps, and then convert them to local time when displaying to users (that's even what your workaround with pytz does). Saying "UTC is irrelevant, and actually a nuisance" just shows your inexperience in dealing with datetimes. I'm utterly confused how you don't seem to get the benefits of the universal nature of UTC.
|
-9

I know I am tremendously late in replying to this.

I have tried doing this recently and therefore I suggest using datetime.now() instead of datetime.utcnow(). For my simple application that works fine.

1 Comment

As the name suggests, utcnow() and now() are not the same thing. datetime.now() returns the local date.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.