igomez
igomez

Reputation: 39

Subtracting datetime's in Python

So I'm trying to implement a timing routine and I need to return the seconds (secs) so that my timing routine starts my lights. The original code that I researched got me fairly far:

from datetime import datetime
from threading import Timer

x=datetime.today()
y=x.replace(day=x.day+1, hour=1, minute=0, second=0, microsecond=0)
delta_t=y-x

secs=delta_t.seconds+1

def hello_world():
    print "hello world"
    #...

t = Timer(secs, hello_world)
t.start()

The only issue is that I took in the x.replace as a user input variable and now I get the error "TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'"

I understand it's because you can't directly subtract two datetime.datetime.time() directly but I'm unsure on how to convert them into something that I can operate with. Here's my code so far

import datetime
from threading import Timer
import tkinter as tk
import time

# =============================================================================
# userInput takes a formatted input and passes it back to main.
# =============================================================================
def userInput():
        try:
            a = datetime.datetime.strptime(input('When would you like to routine to start in HH:MM 24 hour format: '), "%H:%M").time()
            print (a.strftime("%H:%M"))
        except:
            print ("Please enter correct time in HHMM format")
        return a

# =============================================================================
# timeComparator is a function which, if the user changes any settings or chooses
# start in the middle of a cycle, implements the correct routine depending on where
# in the cycle it's in.
# =============================================================================            
def timeComparator(a):
    now = datetime.datetime.now().time()
    #this obtains the current time
    #if statement compares input from 
    print("the time now is: ", now)
    if (now < a):
        print ("hello human")
    elif (now > a):
        print ("hello plant")

# =============================================================================
# This routine is hard coded and cannot be changed by the user. It assumes that 
# there will be a total of 12 hours of light with the last hour, in other words
# the last 8% of light, shifting from a natural blue hue to a more red hue. 
# The auto routine will start at 8am and end at 8pm. By ending, the routine 
# stops light shifting and finally at 830PM, the lights turn off.
# NOTE NOTE NOTE NOTE NOTE
# This is NOT the actual light routine. This is JUST function that records
# the time and returns the seconds that begins the start command for the lights
# =============================================================================
def autoRoutine(a):
    now = datetime.datetime.now().time()
    #this is the start of the auto routine
    start=a
    delta_t = start-now

    secs = delta_t.seconds+1
    return secs

def blueFade():
    print("the lights are starting")
# =============================================================================
# Main function. Will be used to call all other functions
# =============================================================================
if __name__=="__main__":

    a = userInput()

    timeComparator(a)

    secs = autoRoutine(a)
    lights = Timer(secs, blueFade)
    lights.start()

So at the end of the day, I'm unable to operate the code line

    delta_t = start-now

and because of this I can't begin the lights.start() function. I have tried using time.strptime to compare but I haven't been successful as well as time.mktime()

Upvotes: 0

Views: 98

Answers (1)

Charlie Wallace
Charlie Wallace

Reputation: 1830

To determine the delta in seconds from now() and a time constructed from hours and minutes we can use time.hour, time.minute and time.second attributes.

The issue in the question's code is that it is trying to do subtraction on two datetime.time objects

def autoRoutine(a):
    now = datetime.datetime.now().time()
    #this is the start of the auto routine
    start=a
    delta_t = start-now

    secs = delta_t.seconds+1
    return secs

This produces:

  File "<ipython-input-18-98011edfef89>", line 65, in autoRoutine
    delta_t = start-now

TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'

To correct we can convert datetime.time to seconds. See convert-datetime-time-to-seconds

Applying this answer to your question we have:

def autoRoutine(a):
    now = datetime.datetime.now().time()
    startSeconds = ((a.hour * 60) + a.minute) * 60
    nowSeconds = (((now.hour * 60) + now.minute) * 60) + now.second
    startSeconds - nowSeconds

Upvotes: 1

Related Questions