How to find next day's Unix timestamp for same hour, including DST, in Python?

dst, localtime, python, pytz, timezone

Solution

Without using a new package:

def add_day(x):
    d = x.date()+DT.timedelta(1)
    return mtl.localize(x.replace(year=d.year, month=d.month, day=d.day, tzinfo=None))

Full script:

import datetime as DT
import pytz
import calendar
mtl = pytz.timezone('America/Montreal')
naive_time3 = DT.datetime.strptime('2013/11/03', '%Y/%m/%d')
print repr(naive_time3)
#datetime.datetime(2013, 11, 3, 0, 0)
localized_time3 = mtl.localize(naive_time3)
print repr(localized_time3)
#datetime.datetime(2013, 11, 3, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EDT-1 day, 20:00:00 DST>)
print calendar.timegm(localized_time3.utctimetuple())
#1383451200.0
def add_day(x):
    d = x.date()+DT.timedelta(1)
    return mtl.localize(x.replace(year=d.year, month=d.month, day=d.day, tzinfo=None))
print repr(add_day(localized_time3))
#datetime.datetime(2013, 11, 4, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EST-1 day, 19:00:00 STD>)

(`calendar` is for Python2.)

Problem

In Python, I can find the Unix time stamp of a local time, knowing the time zone, like this (using pytz): ``` >>> import datetime as DT >>> import pytz >>> mtl = pytz.timezone('America/Montreal') >>> naive_time3 = DT.datetime.strptime('2013/11/03', '%Y/%m/%d') >>> naive_time3 datetime.datetime(2013, 11, 3, 0, 0) >>> localized_time3 = mtl.localize(naive_time3) >>> localized_time3 datetime.datetime(2013, 11, 3, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EDT-1 day, 20:00:00 DST>) >>> localized_time3.timestamp() 1383451200.0 ``` So far, so good. `naive_time` is not aware of the time zone, whereas `localized_time` knows its midnight on 2013/11/03 in Montréal, so the (UTC) Unix time stamp is good. This time zone is also my local time zone and this time stamp seems right: ``` $ date -d @1383451200 Sun Nov 3 00:00:00 EDT 2013 ``` Now, clocks were adjusted one hour backward November 3rd at 2:00 here in Montréal, so we gained an extra hour that day. This means that there were, here, 25 hours between 2013/11/03 and 2013/11/04. This shows it: ``` >>> naive_time4 = DT.datetime.strptime('2013/11/04', '%Y/%m/%d') >>> localized_time4 = mtl.localize(naive_time4) >>> localized_time4 datetime.datetime(2013, 11, 4, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EST-1 day, 19:00:00 STD>) >>> (localized_time4.timestamp() - localized_time3.timestamp()) / 3600 25.0 ``` Now, I'm looking for an easy way to get the `localized_time4` object from `localized_time3`, knowing I want to get the next localized day at the same hour (here, midnight). I tried `timedelta`, but I believe it's not aware of time zones or DST: ``` >>> localized_time4td = localized_time3 + DT.timedelta(1) >>> localized_time4td datetime.datetime(2013, 11, 4, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EDT-1 day, 20:00:00 DST>) >>> (localized_time4td.timestamp() - localized_time3.timestamp()) / 3600 24.0 ``` My purpose is to get informations about log entries that are stored with their Unix timestamp for each local day. Of course, if I use `localized_time3.timestamp()` and add `24 * 3600` here (which will be the same as `localized_time4td.timestamp()`), I will miss all log entries that happened between `localized_time4td.timestamp()` and `localized_time4td.timestamp() + 3600`. In other words, the function or method I'm looking for should know when to add 25 hours, 24 hours or 23 hours sometimes to a Unix time stamp, depending on when DST shifts happen.

Original source

Related problems