277

How do I get the UTC time, i.e. milliseconds since Unix epoch on Jan 1, 1970?

1

9 Answers 9

376

For Python 3, use datetime.now(timezone.utc) to get a timezone-aware datetime, and use .timestamp() to convert it to a timestamp.

from datetime import datetime, timezone datetime.now(timezone.utc) datetime.now(timezone.utc).timestamp() * 1000 # POSIX timestamp in milliseconds 

For your purposes when you need to calculate an amount of time spent between two dates all that you need is to subtract end and start dates. The results of such subtraction is a timedelta object.

From the python docs:

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]) 

And this means that by default you can get any of the fields mentioned in it's definition - days, seconds, microseconds, milliseconds, minutes, hours, weeks. Also timedelta instance has total_seconds() method that:

Return the total number of seconds contained in the duration. Equivalent to (td.microseconds + (td.seconds + td.days * 24 * 3600) * 106) / 106 computed with true division enabled.

For Python 2 (the 2.x solution will technically work, but has a giant warning in the 3.x docs), you would have used datetime.utcnow():

from datetime import datetime datetime.utcnow() 
Sign up to request clarification or add additional context in comments.

4 Comments

possibly nasty surprise about datetime.utcnow() is that is does not return a timezone-aware object despite the name. This is in my opinion a big problem, which is why I prefer my answer below. See "datetime objects with no timezone should be considered as a "bug" in the application." julien.danjou.info/python-and-timezones
The concept of a so called naive datetime object (i.e., no timezone information is set) does serve a purpose: I want my alarm clock to ring at 06:00:00 every day no matter where in the world I am. Also it allows for "virtual clocks" in say computer games: It is now 5 pm in my fantasy world. Forcing a timezone onto the datetime object would be awkward, especially with timedelta arithmetics.
python 3.12 says this is deprecated so use datetime.now(timezone.utc)
answer is not uptodate any more. from datetime import UTC, datetime datetime.now(UTC)
219

Timezone-aware datetime object, unlike datetime.utcnow():

from datetime import datetime,timezone now_utc = datetime.now(timezone.utc) 

Timestamp in milliseconds since Unix epoch:

datetime.now(timezone.utc).timestamp() * 1000 

4 Comments

According to the Python 3 documentation this is the recommended way to do it.
Clean and easy! Should be the preferred way.
@Marry35 yes, this should be the preferred way NOW. When the question was first asked timezone.utc did not exist.
And if you prefer to have the local time (e.g. for easier display to user) but still be timezone-safe, you can use datetime.now().astimezone()
52

In the form closest to your original:

import datetime def UtcNow(): now = datetime.datetime.utcnow() return now 

If you need to know the number of seconds from 1970-01-01 rather than a native Python datetime, use this instead:

return (now - datetime.datetime(1970, 1, 1)).total_seconds() 

Python has naming conventions that are at odds with what you might be used to in Javascript, see PEP 8. Also, a function that simply returns the result of another function is rather silly; if it's just a matter of making it more accessible, you can create another name for a function by simply assigning it. The first example above could be replaced with:

utc_now = datetime.datetime.utcnow 

All of the above is now considered obsolete. Python 3.2 introduced datetime.timezone so that a proper tzinfo for UTC could be available to all. So the modern version becomes:

def utc_now(): return datetime.datetime.now(tz=datetime.timezone.utc) 

7 Comments

@J.F.Sebastian true, but see the comment I made earlier - this is the form closest to the code in the question. No need to confuse people by introducing tangents to their question, unless it's relevant.
There is no reason to promote bad practice without an explicit disclaimer in the answer. I've upvoted your answer but it deserves a comment that shows how it is done idiomatically in Python. Though my comment doesn't follow pep-8 naming convention, to preserve the link with the name used in the question.
(now - datetime.datetime(1970, 1, 1)).total_seconds() ... What about just time.time()?
datetime.datetime.utcnow() does not return a timezone-aware datetime, which is really not a good idea, it's just a question of time before one eventually discovers how horrible that is.
@TimRichardson I don't disagree, but at the time this answer was written there was no alternative - Python didn't include any tzinfo objects, even for UTC.
|
22
import datetime import pytz # datetime object with timezone awareness: datetime.datetime.now(tz=pytz.utc) # seconds from epoch: datetime.datetime.now(tz=pytz.utc).timestamp() # ms from epoch: int(datetime.datetime.now(tz=pytz.utc).timestamp() * 1000) 

2 Comments

pytz is deprecated now that the zoneinfo DB/package has been moved into the Std Lib.
@Marc pytz is not deprecated.
18

Timezone aware with zero external dependencies:

from datetime import datetime, timezone def utc_now(): return datetime.utcnow().replace(tzinfo=timezone.utc) 

4 Comments

inorder to print it in zulu format, this is the way to go datetime.utcnow().replace(tzinfo=timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
How is it different from datetime.now(timezone.utc)? Just curious. cause I believe the result is exactly the same.
@GaganDeepSingh Both give the exact same datetime object. (There are sometimes multiple paths to the same destination.) .replace(tzinfo=timezone.utc) merely sets the .tzinfo member which is unfortunately None by default.
datetime.utcnow() is deprecated in Python 3.12, use another answer instead.
10

From datetime.datetime you already can export to timestamps with method strftime. Following your function example:

import datetime def UtcNow(): now = datetime.datetime.utcnow() return int(now.strftime("%s")) 

If you want microseconds, you need to change the export string and cast to float like: return float(now.strftime("%s.%f"))

3 Comments

What's the point of converting to a string and then back to a number when you can get the number directly?
The point is that you may want to change things on the function and for that reason is better stick to datetime object, not using time.time(), You could also use time.mktime(now.timetuple()) to convert directly to int. Anyway, for this simple case time.time() is also a valid option. What I find odd, is going by timedelta to find the seconds.
Note, that strftime("%s") is platform dependent and does not work on Windows. (At least it doesn't for me on Windows 10).
7

you could use datetime library to get UTC time even local time.

import datetime utc_time = datetime.datetime.utcnow() print(utc_time.strftime('%Y%m%d %H%M%S')) 

1 Comment

What does this 2021 answer add to the conversation? It's the same method as shown in the accepted answer from almost 10 years earlier.
7

As datetime.datetime.utcnow() is deprecated, you can alternatively use the below code to get the time in UTC.

from datetime import datetime, timezone datetime.now(timezone.utc) 

1 Comment

missing import from datetime import datetime,timezone
6

why all reply based on datetime and not time? i think is the easy way !

import time nowgmt = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) print(nowgmt) 

3 Comments

nowgmt will be a string, which is less flexible than having a datetime object
But faster as per @Jagerber48 Under the hood datetime.datetime.now() uses time.time(). With this knowledge this question boils down to the question of should we use time.time() ... As explained in this answer...
UTC with milliseconds for OP s, ms = divmod(1236472051807, 1000) mstime = '%s.%03d' % (time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(s)), ms) as per @falsetru

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.