Skip to content
Advertisement

how can i calculate the difference between two dates and times in python

my code looks like this:

from datetime import datetime

namesFile = open("data.txt", "r") 
listaDati = namesFile.readlines()

sensors_dict = {#i'm omitting what's wrote in here because it's not relevant}

listaDivisa = []
for i in listaDati:
    if "T" not in i:
        listaDivisa.append(
            i.split()) 

for k, v in sensors_dict.items():  #mapping sensor's name with the ones in the dict
    for i in listaDivisa:
        if i[2] == k:
            i[2] = v
for i in listaDivisa:  #mapping in simply "on" and "off"
    if i[3] in ["ON", "OPEN", "ON0", "ON`", "O"]:
        i[3] = "ON"
    elif i[3] in ["OFF", "CLOSE"]:
        i[3] = "OFF"

listaDivisa looks like this:

['2009-10-16', '21:06:34.00044', 'kitchen sensor', 'ON']
['2009-10-16', '21:13:22.00016, 'kitchen sensor', 'OFF']
['2009-10-16', '12:53:29.00004', 'bathroom sensor', 'ON']
['2009-10-16', '14:02:51.00056, 'bathroom sensor', 'OFF']

... and so on 

I want to calculate how much time (better in minutes) the sensor was ON, I tried doing this:

def differenza():
    for p, j in enumerate(listaDivisa[:-1]):
        if j[2] == listaDivisa[p + 1][2]:
            if j[3] == "ON" and listaDivisa[p + 1][3] == "OFF":
                tempo1 = j[0] + " " + j[1]
                tempo2 = listaDivisa[p + 1][0] + " " + listaDivisa[p + 1][1]

                d1 = datetime.strptime(tempo1, '%Y-%m-%d %H:%M:%S.%f')
                d2 = datetime.strptime(tempo2, '%Y-%m-%d %H:%M:%S.%f')

                return abs((d2 - d1).seconds)


listaDict = {}
for i in listaDivisa:
    if i[0] not in listaDict.keys():
        listaDict[i[2]] = dict()

    r = differenza()
    listaDict[i[2]][i[0]] = "day " + i[0] + " sensor have been active for " + str(r) + " seconds"

for key, value in listaDict.items():
    print(key, ' : ', value)

but it doesn’t work, another raw alternative I tried was

def differenza():
    for i in range(len(listaDivisa)):
        for j in range(i + 1, len(listaDivisa)):
            if listaDivisa[i][2] == listaDivisa[j][2]:
                if listaDivisa[i][3] == "ON" and listaDivisa[j][3] == "OFF":
                    timeStart = listaDivisa[i][1].split(":")
                    timeFinish= listaDivisa[j][1].split(
                        ":")
                    time1 = [int((timeStart[0] * 3600)), int((timeStart[1] * 60))]
                    time2= [int((timeFinish[0] * 3600)), int((timeFinish[1] * 60))]
                    secondsStart= sum(time1)
                    secondsFinish= sum(time2)
                    secondsDifference= secondsFinish - secondsStart
                    minutes= secondsDifference / 60

                    ris = "Sensor active for " + str(minutes) + " minutes"
                    return ris

but, not minding about the fact that it doesn’t even work, I don’t think it could be a smart alternative.

How could I do that? Thank you

Advertisement

Answer

Ignoring how listaDivisa is constructed in OP’s code then this may help:

from datetime import datetime

ON = 'ON'
OFF = 'OFF'

listaDivisa = [['2009-10-16', '21:06:34.00044', 'kitchen sensor', 'ON'],
               ['2009-10-16', '21:13:22.00016', 'kitchen sensor', 'OFF'],
               ['2009-10-16', '12:53:29', 'bathroom sensor', 'ON'],
               ['2009-10-16', '14:02:51.00056', 'bathroom sensor', 'OFF']]

results = {}

for date_, time_, sensor_, state_ in listaDivisa:
    for fmt in '%Y-%m-%d%H:%M:%S.%f', '%Y-%m-%d%H:%M:%S':
        try:
            results.setdefault(sensor_, {})[state_] = datetime.strptime(f'{date_}{time_}', fmt)
            break
        except ValueError:
            pass

for k, v in results.items():
    if ON in v and OFF in v:
        print(k, (v[OFF]-v[ON]).seconds)

Output:

kitchen sensor 407
bathroom sensor 4162
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement