Search code examples
pythondatetimetimeepoch

Epoch time is one hour out from UTC, should be UTC+1


I have written a module that generates a percentage chance of events happening during a specific time. My database has a timestamp of when events are generated. I am converting the timetamp which is in y-m-d h-m-s format into epoch time. The epoch time that I am getting is in UTC (GMT) time where as my time zone is GMT + 1.

An example as follows:

My first database entry is at 10:13:36 which has an epoch time of 1397211216, when I attempt to get the epoch time for this entry from within my code the epoch time that is returned is 1397207617 (09:13:36). My code is below, I know there is an issue with how my epoch time is defined but I can't figure out how to alter it to get the correct time.

def getPercentageDuringTime(dbName, sensorType, beginningTime, endTime):
    count = 0
    reading = [i [1]for i in cur.execute("SELECT * FROM " + dbName + " WHERE sensor = '" + sensorType + "' ")] 
    readingtime = [i [2] for i in cur.execute("SELECT * FROM " + dbName + " WHERE sensor = '" + sensorType + "' ")] 
    for i in range(len(reading)):
        pattern = '%Y-%m-%d %H:%M:%S'
        epoch = int(time.mktime(time.strptime(readingtime[i], pattern)))
        if ((epoch >= beginningTime) and (epoch <= endTime)):
            count = count + 1
    percentage = count / (len(reading)) * 100

    print (epoch)
    return percentage

print (getPercentageDuringTime('event4312593', 'sound', 1397207617, 1397207616))

Solution

  • The time.mktime() function is the inverse of time.localtime(), so your parsed time is interpreted as UTC, then moved to your local timezone.

    What you need to use here instead is the inverse of time.gmtime() instead, which is helpfully hidden in a different module: the calendar.timegm() function:

    >>> import time, calendar
    >>> sample = '2014-04-11 10:13:36'
    >>> int(time.mktime(time.strptime(sample, pattern)))
    1397207616
    >>> int(calendar.timegm(time.strptime(sample, pattern)))
    1397211216
    

    Instead of using offsets from the UNIX epoch, consider using the datetime module instead; it would let you handle the timestamps without having to worry about timezone considerations, which is perfectly fine for your needs:

    >>> import datetime
    >>> datetime.datetime.strptime(sample, pattern)
    datetime.datetime(2014, 4, 11, 10, 13, 36)
    

    If you have to pass in timestamps (seconds since the UNIX epoch), you can convert those to datetime objects with datetime.datetime.fromtimestamp():

    >>> datetime.datetime.fromtimestamp(1397207617)
    datetime.datetime(2014, 4, 11, 10, 13, 37)
    

    which gives you a datetime object by interpreting the value in your machine-local timezone.