0

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()

igomez
  • 39
  • 5

1 Answers1

1

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
Charlie Wallace
  • 1,810
  • 1
  • 15
  • 17
  • I'm implementing this now, Charlie. I do have some questions. In the first code example, I could run it as is and it was fine. Why is that different to what I have in my code? Also, I would still need to add a line to your last snippet, correct? ``` secs = startSeconds-nowSeconds ``` – igomez Apr 06 '19 at 16:26
  • On the part of your question, "I would still need sec = ... " the answer is you do not have to have secs. The last expression of a python function is returned. – Charlie Wallace Apr 07 '19 at 01:57
  • On the part, "why is that different" I will have to take a look tomorrow. I am away from my computer tonight. – Charlie Wallace Apr 07 '19 at 02:00
  • I didn't know that about Python thank you! Also, everything works. I really appreciate it. I was pulling my hair out! – igomez Apr 07 '19 at 20:14