Is there a way to get the UTC timestamp by specifying the date? What I would expect:
datetime(2008, 1, 1, 0, 0, 0, 0)
should result in
1199145600
Creating a naive datetime object means that there is no time zone information. If I look at the documentation for datetime.utcfromtimestamp, creating a UTC timestamp means leaving out the time zone information. So I would guess, that creating a naive datetime object (like I did) would result in a UTC timestamp. However:
then = datetime(2008, 1, 1, 0, 0, 0, 0)
datetime.utcfromtimestamp(float(then.strftime('%s')))
results in
2007-12-31 23:00:00
Is there still any hidden time zone information in the datetime object? What am I doing wrong?
Naïve
datetimeversus awaredatetimeDefault
datetimeobjects are said to be “naïve”: they keep time information without the time zone information. Think about naïvedatetimeas 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
datetimeas 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
+4targets if we don’t know from where to start ?). This is why you can’t have adatetime.datetime.toutctimestamp()method. (cf: http://bugs.python.org/issue1457227)To check if your
datetimedtis naïve, checkdt.tzinfo, ifNone, then it’s naïve: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
datetimeon UTC ? or was it local time ?If you were using UTC (you are out of trouble):
If you were NOT using UTC, welcome to hell.
You have to make your
datetimenon-naïve prior to using the formerfunction, 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):
Consequences of not providing
is_dst:Not using
is_dstwill 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_dstwill of course generate incorrecttime (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_dstwill give an interpretation ofhow to consider this bogus time, and this is the only case where
.normalize(..)will actually do something here, as it’ll thentranslate it as an actual valid time (changing the datetime AND the
DST object if required). Note that
.normalize()is not requiredfor 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)
Why? because
.replace()replaces blindly thetzinfowithouttaking into account the target time and will choose a bad DST object.
Whereas
.localize()uses the target time and youris_dsthintto 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
datetimeobject 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.mktimewe can create anutc_mktime:You must make sure that your
datetimeobject is created on the same timezone than the one that has created yourdatetime.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).