Naïve datetime versus aware datetime

Default datetime objects are said to be "naïve": they keep time information without the time zone information. Think about naïve datetime as a relative number (ie: +4) without a clear origin (in fact your origin will be common throughout your system boundary).

In contrast, think about aware datetime as absolute numbers (ie: 8) with a common origin for the whole world.

Without timezone information you cannot convert the "naive" datetime towards any non-naive time representation (where does +4 targets if we don't know from where to start ?). This is why you can't have a datetime.datetime.toutctimestamp() method. (cf: http://bugs.python.org/issue1457227)

To check if your datetime dt is naïve, check dt.tzinfo, if None, then it's naïve:

datetime.now()        ## DANGER: returns naïve datetime pointing on local time
datetime(1970, 1, 1)  ## returns naïve datetime pointing on user given time

I have naïve datetimes, what can I do ?

You must make an assumption depending on your particular context: The question you must ask yourself is: was your datetime on UTC ? or was it local time ?

  • If you were using UTC (you are out of trouble):

    import calendar
    
    def dt2ts(dt):
        """Converts a datetime object to UTC timestamp
    
        naive datetime will be considered UTC.
    
        """
    
        return calendar.timegm(dt.utctimetuple())
    
  • If you were NOT using UTC, welcome to hell.

    You have to make your datetime non-naïve prior to using the former function, by giving them back their intended timezone.

    You'll need the name of the timezone and the information about if DST was in effect when producing the target naïve datetime (the last info about DST is required for cornercases):

    import pytz     ## pip install pytz
    
    mytz = pytz.timezone('Europe/Amsterdam')             ## Set your timezone
    
    dt = mytz.normalize(mytz.localize(dt, is_dst=True))  ## Set is_dst accordingly
    

    Consequences of not providing is_dst:

    Not using is_dst will generate incorrect time (and UTC timestamp) if target datetime was produced while a backward DST was put in place (for instance changing DST time by removing one hour).

    Providing incorrect is_dst will of course generate incorrect time (and UTC timestamp) only on DST overlap or holes. And, when providing also incorrect time, occuring in "holes" (time that never existed due to forward shifting DST), is_dst will give an interpretation of how to consider this bogus time, and this is the only case where .normalize(..) will actually do something here, as it'll then translate it as an actual valid time (changing the datetime AND the DST object if required). Note that .normalize() is not required for having a correct UTC timestamp at the end, but is probably recommended if you dislike the idea of having bogus times in your variables, especially if you re-use this variable elsewhere.

    and AVOID USING THE FOLLOWING: (cf: Datetime Timezone conversion using pytz)

    dt = dt.replace(tzinfo=timezone('Europe/Amsterdam'))  ## BAD !!
    

    Why? because .replace() replaces blindly the tzinfo without taking into account the target time and will choose a bad DST object. Whereas .localize() uses the target time and your is_dst hint to select the right DST object.

OLD incorrect answer (thanks @J.F.Sebastien for bringing this up):

Hopefully, it is quite easy to guess the timezone (your local origin) when you create your naive datetime object as it is related to the system configuration that you would hopefully NOT change between the naive datetime object creation and the moment when you want to get the UTC timestamp. This trick can be used to give an imperfect question.

By using time.mktime we can create an utc_mktime:

def utc_mktime(utc_tuple):
    """Returns number of seconds elapsed since epoch

    Note that no timezone are taken into consideration.

    utc tuple must be: (year, month, day, hour, minute, second)

    """

    if len(utc_tuple) == 6:
        utc_tuple += (0, 0, 0)
    return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))

def datetime_to_timestamp(dt):
    """Converts a datetime object to UTC timestamp"""

    return int(utc_mktime(dt.timetuple()))

You must make sure that your datetime object is created on the same timezone than the one that has created your datetime.

This last solution is incorrect because it makes the assumption that the UTC offset from now is the same than the UTC offset from EPOCH. Which is not the case for a lot of timezones (in specific moment of the year for the Daylight Saving Time (DST) offsets).

Answer from vaab on Stack Overflow
Top answer
1 of 11
115

Naïve datetime versus aware datetime

Default datetime objects are said to be "naïve": they keep time information without the time zone information. Think about naïve datetime as a relative number (ie: +4) without a clear origin (in fact your origin will be common throughout your system boundary).

In contrast, think about aware datetime as absolute numbers (ie: 8) with a common origin for the whole world.

Without timezone information you cannot convert the "naive" datetime towards any non-naive time representation (where does +4 targets if we don't know from where to start ?). This is why you can't have a datetime.datetime.toutctimestamp() method. (cf: http://bugs.python.org/issue1457227)

To check if your datetime dt is naïve, check dt.tzinfo, if None, then it's naïve:

datetime.now()        ## DANGER: returns naïve datetime pointing on local time
datetime(1970, 1, 1)  ## returns naïve datetime pointing on user given time

I have naïve datetimes, what can I do ?

You must make an assumption depending on your particular context: The question you must ask yourself is: was your datetime on UTC ? or was it local time ?

  • If you were using UTC (you are out of trouble):

    import calendar
    
    def dt2ts(dt):
        """Converts a datetime object to UTC timestamp
    
        naive datetime will be considered UTC.
    
        """
    
        return calendar.timegm(dt.utctimetuple())
    
  • If you were NOT using UTC, welcome to hell.

    You have to make your datetime non-naïve prior to using the former function, by giving them back their intended timezone.

    You'll need the name of the timezone and the information about if DST was in effect when producing the target naïve datetime (the last info about DST is required for cornercases):

    import pytz     ## pip install pytz
    
    mytz = pytz.timezone('Europe/Amsterdam')             ## Set your timezone
    
    dt = mytz.normalize(mytz.localize(dt, is_dst=True))  ## Set is_dst accordingly
    

    Consequences of not providing is_dst:

    Not using is_dst will generate incorrect time (and UTC timestamp) if target datetime was produced while a backward DST was put in place (for instance changing DST time by removing one hour).

    Providing incorrect is_dst will of course generate incorrect time (and UTC timestamp) only on DST overlap or holes. And, when providing also incorrect time, occuring in "holes" (time that never existed due to forward shifting DST), is_dst will give an interpretation of how to consider this bogus time, and this is the only case where .normalize(..) will actually do something here, as it'll then translate it as an actual valid time (changing the datetime AND the DST object if required). Note that .normalize() is not required for having a correct UTC timestamp at the end, but is probably recommended if you dislike the idea of having bogus times in your variables, especially if you re-use this variable elsewhere.

    and AVOID USING THE FOLLOWING: (cf: Datetime Timezone conversion using pytz)

    dt = dt.replace(tzinfo=timezone('Europe/Amsterdam'))  ## BAD !!
    

    Why? because .replace() replaces blindly the tzinfo without taking into account the target time and will choose a bad DST object. Whereas .localize() uses the target time and your is_dst hint to select the right DST object.

OLD incorrect answer (thanks @J.F.Sebastien for bringing this up):

Hopefully, it is quite easy to guess the timezone (your local origin) when you create your naive datetime object as it is related to the system configuration that you would hopefully NOT change between the naive datetime object creation and the moment when you want to get the UTC timestamp. This trick can be used to give an imperfect question.

By using time.mktime we can create an utc_mktime:

def utc_mktime(utc_tuple):
    """Returns number of seconds elapsed since epoch

    Note that no timezone are taken into consideration.

    utc tuple must be: (year, month, day, hour, minute, second)

    """

    if len(utc_tuple) == 6:
        utc_tuple += (0, 0, 0)
    return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))

def datetime_to_timestamp(dt):
    """Converts a datetime object to UTC timestamp"""

    return int(utc_mktime(dt.timetuple()))

You must make sure that your datetime object is created on the same timezone than the one that has created your datetime.

This last solution is incorrect because it makes the assumption that the UTC offset from now is the same than the UTC offset from EPOCH. Which is not the case for a lot of timezones (in specific moment of the year for the Daylight Saving Time (DST) offsets).

2 of 11
37

Another possibility is:

d = datetime.datetime.utcnow()
epoch = datetime.datetime(1970,1,1)
t = (d - epoch).total_seconds()

This works as both "d" and "epoch" are naive datetimes, making the "-" operator valid, and returning an interval. total_seconds() turns the interval into seconds. Note that total_seconds() returns a float, even d.microsecond == 0

🌐
Programiz
programiz.com › python-programming › datetime › timestamp-datetime
Python timestamp to datetime and vice-versa (With Examples)
December 25, 2018 - from datetime import datetime # timestamp is number of seconds since 1970-01-01 timestamp = 1545730073 # convert the timestamp to a datetime object in the local timezone dt_object = datetime.fromtimestamp(timestamp) # print the datetime object and its type print("dt_object =", dt_object) print("type(dt_object) =", type(dt_object)) ... Here, we have imported the datetime class from the datetime module.
Discussions

Converting datetime.date to UTC timestamp in Python - Stack Overflow
I am dealing with dates in Python and I need to convert them to UTC timestamps to be used inside Javascript. The following code does not work: >>> d = datetime.date(2011,01,01) >>> More on stackoverflow.com
🌐 stackoverflow.com
Converting UTC datetime to timestamp, and then back to UTC datetime
timestamp = datetime.datetime.now().timestamp() edit: sorry that was local time timestamp = datetime.datetime.utcnow().timestamp() More on reddit.com
🌐 r/learnpython
4
1
October 12, 2016
Converting python datetime to timestamp and back in UTC still uses local timezone - Stack Overflow
I'm working with a code that gives me utc timestamps and I want to convert them to appropriate datetimes. Unfortunately when I test simple cases with pytz the datetime has an added 6 hours (the CST More on stackoverflow.com
🌐 stackoverflow.com
python - Convert to UTC Timestamp - Stack Overflow
Why is that only applicable to Python 3? It seems to run fine in 2.7. 2016-07-18T16:54:54.61Z+00:00 ... A -1 because of AttributeError: module 'datetime' has no attribute 'utcfromtimestamp' 2020-03-29T11:49:38.893Z+00:00 ... The docs give an example of this using the astimezone() method here. Additionally, if you're going to be dealing with timezones, you might want to look into the PyTZ library which has lots of helpful tools for converting datetime... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GeeksforGeeks
geeksforgeeks.org › python › convert-datetime-to-utc-timestamp-in-python
Convert Datetime to UTC Timestamp in Python - GeeksforGeeks
July 1, 2025 - Converting a Datetime to a UTC Timestamp in Python means transforming a date and time into the number of seconds since the Unix epoch (January 1, 1970, UTC), while correctly accounting for time zones.
🌐
Python documentation
docs.python.org › 3 › library › datetime.html
datetime — Basic date and time types
Because naive datetime objects ... an object representing a specific timestamp in UTC is by calling datetime.fromtimestamp(timestamp, tz=timezone.utc)....
Top answer
1 of 12
555

If d = date(2011, 1, 1) is in UTC:

>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)

If d is in local timezone:

>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)

timestamp1 and timestamp2 may differ if midnight in the local timezone is not the same time instance as midnight in UTC.

mktime() may return a wrong result if d corresponds to an ambiguous local time (e.g., during DST transition) or if d is a past(future) date when the utc offset might have been different and the C mktime() has no access to the tz database on the given platform. You could use pytz module (e.g., via tzlocal.get_localzone()) to get access to the tz database on all platforms. Also, utcfromtimestamp() may fail and mktime() may return non-POSIX timestamp if "right" timezone is used.


To convert datetime.date object that represents date in UTC without calendar.timegm():

DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY

How can I get a date converted to seconds since epoch according to UTC?

To convert datetime.datetime (not datetime.date) object that already represents time in UTC to the corresponding POSIX timestamp (a float).

Python 3.3+

datetime.timestamp():

from datetime import timezone

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

Note: It is necessary to supply timezone.utc explicitly otherwise .timestamp() assume that your naive datetime object is in local timezone.

Python 3 (< 3.3)

From the docs for datetime.utcfromtimestamp():

There is no method to obtain the timestamp from a datetime instance, but POSIX timestamp corresponding to a datetime instance dt can be easily calculated as follows. For a naive dt:

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

And for an aware dt:

timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)

Interesting read: Epoch time vs. time of day on the difference between What time is it? and How many seconds have elapsed?

See also: datetime needs an "epoch" method

Python 2

To adapt the above code for Python 2:

timestamp = (dt - datetime(1970, 1, 1)).total_seconds()

where timedelta.total_seconds() is equivalent to (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 computed with true division enabled.

Example

from __future__ import division
from datetime import datetime, timedelta

def totimestamp(dt, epoch=datetime(1970,1,1)):
    td = dt - epoch
    # return td.total_seconds()
    return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6 

now = datetime.utcnow()
print now
print totimestamp(now)

Beware of floating-point issues.

Output

2012-01-08 15:34:10.022403
1326036850.02

How to convert an aware datetime object to POSIX timestamp

assert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+

On Python 3:

from datetime import datetime, timedelta, timezone

epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)

On Python 2:

# utc time = local time              - utc offset
utc_naive  = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()
2 of 12
117

For unix systems only:

>>> import datetime
>>> d = datetime.date(2011, 1, 1)
>>> d.strftime("%s")  # <-- THIS IS THE CODE YOU WANT
'1293832800'

Note 1: dizzyf observed that this applies localized timezones. Don't use in production.

Note 2: Jakub Narębski noted that this ignores timezone information even for offset-aware datetime (tested for Python 2.7).

🌐
Reddit
reddit.com › r/learnpython › converting utc datetime to timestamp, and then back to utc datetime
r/learnpython on Reddit: Converting UTC datetime to timestamp, and then back to UTC datetime
October 12, 2016 -

I'm having trouble taking a UTC datetime, converting it to a timestamp, and then converting that timestamp back into a datetime object. I have read this post and this post, but following the answers isn't working for me either.

I'm using Python 3.4

I'm trying to use timezone-aware datetimes, but I suspect I am not doing it correctly. Here is an example of what I'm trying:

import datetime
import pytz

now = datetime.datetime.utcnow()
timestamp = now.timestamp()

now2 = datetime.datetime.utcfromtimestamp(timestamp)

This does not work. I've also tried to replace the last line with:

now2 = datetime.datetime.utcfromtimestamp(timestamp).replace(pytz.utc)

But that gave me a datetime with the same hours, just with an extra timezone object inside the datetime object.

I need now2 to equal now. I don't care about my local timezone. I need this all to be in UTC.

What am I missing?

Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › python › get-utc-timestamp-in-python
Get UTC timestamp in Python - GeeksforGeeks
July 12, 2025 - utc_time.timestamp() converts the datetime object utc_time to a Unix timestamp (the number of seconds since January 1, 1970, 00:00:00 UTC).
🌐
TutorialsPoint
tutorialspoint.com › how-do-i-convert-a-datetime-to-a-utc-timestamp-in-python
How do I convert a datetime to a UTC timestamp in Python?
May 19, 2025 - We can use the datetime module to convert a datetime to a UTC timestamp in Python. If we already have the datetime object in UTC, then the timestamp() function can be directly used to get a UTC timestamp. This function returns the time since epoch fo
🌐
InfluxData
influxdata.com › home › how to convert timestamp to datetime in python | influxdata
How to Convert Timestamp to DateTime in Python | InfluxData
June 28, 2023 - Converting a timestamp to a datetime object is a common task when dealing with time-related data. Python’s datetime module comes to the rescue with the fromtimestamp() function, which allows us to easily perform this conversion.
🌐
Flexiple
flexiple.com › python › python-unix-timestamp
Converting DateTime to UNIX Timestamp in Python - Flexiple
Datetime to Unix TimestampDatetime to Unix Timestamp in UTC TimezoneDatetime.date to Unix TimestampDateTime String to Unix Timestamp ... Converting DateTime to UNIX Timestamp in Python transforms a standard date and time format into a UNIX timestamp, which is the number of seconds that have elapsed in current time since January 1, 1970 (UTC).
🌐
Stephencharlesweiss
stephencharlesweiss.com › converting-timestamps-to-utc-in-python
converting timestamps to utc in python | /*code-comments*/
In order to create a timestamp in Python from a string, it needs to be in ISO format. This actually is the format that my timestamps were coming in. >>> from datetime import datetime >>> dt_str = "2020-06-18T14:55:28-05:00" >>> datetime.fromisoformat(dt_str) >>> dt_str datetime.datetime(2020, 6, 18, 14, 55, 28, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400))) If I could simply convert this to UTC and print that, the whole problem would be simple.
🌐
Sling Academy
slingacademy.com › article › python-convert-datetime-to-timestamp-and-vice-versa
Python: Convert Datetime to Timestamp and vice versa - Sling Academy
December 21, 2022 - from datetime import datetime timestamp = 1636208759.0 dt = datetime.fromtimestamp(timestamp) print(dt) print(type(dt)) # If you want to convert the timestamp to UTC time, use the following code: # dt = datetime.utcfromtimestamp(timestamp) ... In this article, you have learned how to convert ...
🌐
Medium
medium.com › @life-is-short-so-enjoy-it › python-datetime-utcnow-maybe-no-more-for-me-221795e8ddbf
python: datetime.utcnow() — maybe no more for me | by Life-is-short--so--enjoy-it | Medium
February 24, 2023 - The output that got my attention was the output of datetime.utcnow().timestamp() which is 1601444278 on UTC+7 timezone. Initially, I thought that maybe the user who answered made a mistake or a typo while having written the answer. To confirm the value, I copied the code the user shared in the post and ran on my local machine.
🌐
Edureka Community
edureka.co › home › community › categories › python › how to convert datetime date to utc timestamp in...
How to convert datetime date to UTC timestamp in Python | Edureka Community
October 31, 2018 - I need to convert date to UTC timestamps to be used inside Javascript. The following code does ... ).localize(input_date).utctimetuple()) does work.
🌐
Python Morsels
pythonmorsels.com › converting-to-utc-time
Converting datetime to UTC in Python - Python Morsels
December 20, 2021 - While Python's datetime objects do have a utcnow method: >>> datetime.datetime.utcnow() datetime.datetime(2030, 4, 1, 8, 15, 59, 89013) This method was deprecated in Python 3.12 and the Python documentation recommends passing the target timezone ...
🌐
DEV Community
dev.to › jcmorrow › converting-between-datetimes-and-timestamps-in-python-2fag
Converting Between Datetimes and Timestamps in Python - DEV Community
January 29, 2019 - In this case, it will assume it is in your local timezone, which will be a major problem if you don't live in UTC and you try to round-trip your timestamp like above. I solved this by adding an additional step anytime we needed to convert between naive datetimes and timestamps: converting to an aware datetime positioned in UTC.
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.to_datetime.html
pandas.to_datetime — pandas 3.0.1 documentation - PyData |
If True, the function always returns a timezone-aware UTC-localized Timestamp, Series or DatetimeIndex.
🌐
PYnative
pynative.com › home › python › python datetime › timestamp in python
Python Timestamp With Examples – PYnative
December 5, 2021 - If the object is naive, we can assign the UTC value to the tzinfo parameter of the datetime object and then call the timestamp() method.