1

Welp, I'm a noob when it comes to Python. No doubt about it. Have done some VBS and VB so I have a bit of understanding.

What I am tasked to do using Python seems easy: run an action only during these times:

Mon: between 1:30 am and 7:30 am
Tues – Fri: between 3:00 am 7:30 am
Sat: between 1:00 am and 9:00 am and 5:00 pm to Midnight
Sun: Midnight to 8:30 am

Trouble is, all I've been able to come up with is this (and I'm not even sure this is working properly):

import time

def IsOffHour(time):
    if (time.tm_wday > 4):
        return True
    elif (time.tm_hour >= 17):
        return True
    elif (time.tm_hour < 8):
        return True
    else:
        return False

now = time.localtime()
if IsOffHour(now):
    print 'hello cruel world !'

I'm not sure how to handle the times that start at :30. It's been a bit hard to test, maybe I can change the system date and dime to test it out.

It seems like I'm close, open to ideas.

Thanks!

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
Dorkygrin
  • 11
  • 3

3 Answers3

2

Instead of using the time module you should try the datetime module. It's much easier for tasks like these.

If you use a fictional date (or replace the date in your checks) than you can do it like this:

>>> x = datetime.datetime(1, 1, 1, 13, 37, 40)
>>> a = datetime.datetime(1, 1, 1, 1, 30, 0)
>>> b = datetime.datetime(1, 1, 1, 7, 30, 0)
>>> a < x < b
False

>>> x = datetime.datetime(1, 1, 1, 5, 0, 0)
>>> a < x < b
True
Wolph
  • 78,177
  • 11
  • 137
  • 148
  • Wolph - thanks for the suggestion. Do you know how the script might handle Daylight Savings Time changes? – Dorkygrin Dec 05 '10 at 19:07
  • Also, I keep getting this error: Python error : global name 'datetime' is not defined , line 29 , line 20 ========== open to suggestions !!!! – Dorkygrin Dec 05 '10 at 20:11
  • @Dorkygrin: If you put `import datetime` above the code, it will work :) As for handling daylight savings time, I would recommend using the timezones from `pytz`: http://pytz.sourceforge.net/ – Wolph Dec 06 '10 at 01:31
0

My ideas:

  1. do check for each day separately (if time_wday == ... or if time_wday in [...])
  2. for checking hours convert them to 24h based string (there is strftime()) and then compare as strings, so instead of time.tm_hour >= .. this will look as hrstr > '13:30' and hrstr < '19:30'

this gives code like:

def IsOffHour(dt):
    hrstr = '%02d:%02d' % (dt.tm_hour, dt.tm_min)
    if dt.tm_wday == 0:
        return '01:30' <= hrstr <= '07:30'
    if dt.tm_wday in [1, 2, 3, 4]:
        return '03:00' <= hrstr <= '07:30'
    if dt.tm_wday == 5:
        return '01:00' <= hrstr <= '09:00' or hrstr >= '17:00'
    if dt.tm_wday == 6:
        return hrstr <= '08:30'
    return False
Michał Niklas
  • 53,067
  • 18
  • 70
  • 114
  • Thanks for the reply !Thats a different approach! Just tried it but my "if IsOffHour(dt):" statement returns "dt not defined". – Dorkygrin Dec 03 '10 at 14:00
  • In your example `IsOffHour` function had `time` parameter. Name `time` is also name of one of the standard modules (you even use it), so I changed that name to `dt`. But use of `IsOffHour` is the same regardless parameter name. So you must use it as in your example: `if IsOffHour(now):` – Michał Niklas Dec 03 '10 at 21:28
  • Hi Michal - I was just asked if anything of the methods suggested handled Daylight Savings Time without any modification. Any ideas? – Dorkygrin Dec 05 '10 at 19:06
  • Why do you care about DST? All methods will handle DST while it is handled by the OS (`time.localtime()` reads OS time). I think you could not care about DST. I also think that you should read Python tutorial because your problems with my and others responses shows that you not even tried to read basic tutorial (docs from http://www.python.org/) – Michał Niklas Dec 05 '10 at 22:18
  • Ohh. it seems that `time` module does not behave as I described. Look here: http://www.reddit.com/r/Python/comments/egjmh/how_does_the_time_module_react_to_time_changes/ and of course on SO: http://stackoverflow.com/questions/4360981/make-python-respond-to-windows-timezone-changes – Michał Niklas Dec 06 '10 at 08:45
0

What you should be doing is comparing time objects to time objects rather than extracting the hours and minutes and doing this by hand.

So define the acceptable time windows in your script using time objects and then just see if the current time falls in any of the those windows.

from datetime import datetime,time

# Set our allowed time windows in a dictionay indexed by day, with 0 =
# Monday, 1 = Tuesday etc.  Each value is list of tuples, the tuple
# containing the start and end time of each window in that day
off_windows = {
    0: [(time(1,30),time(7,30))],
    1: [(time(3,0),time(7,30))],
    2: [(time(3,0),time(7,30))],
    3: [(time(3,0),time(7,30))],
    4: [(time(3,0),time(7,30))], 
    5: [(time(1,0),time(9,0)),(time(16,0),time.max)],  #time.max is just before midnight
    6: [(time(0,0),time(8,30))]
}


def is_off_hours():
    # Get current datetime
    current = datetime.now()

    # get day of week and time
    current_time = current.time()
    current_day = current.weekday()

    # see if the time falls in any of the windows for today
    return any(start <= current_time <= end for (start,end) in off_windows[current_day])

if is_off_hours():
    print 'Hello cruel world!'

Above we use the any function which returns True if any value of an iterable is True. So he code loops through the off windows which we have defined for a day, returning true if the current time falls within any of them.

A nice this about python is we can say:

start <= current_time <= end 

instead of

start <= current_time and current_time <= end 
David Webb
  • 190,537
  • 57
  • 313
  • 299
  • Another nice approach. I'm learning lots here. Not sure where I would put the Print command? – Dorkygrin Dec 03 '10 at 16:21
  • @Dorkygrin - added the `print` to my example. – David Webb Dec 03 '10 at 17:17
  • Dave - I've been trying lots of stuff to get rid of the following error: Python error : global name 'datetime' is not defined , line 29 , line 20 – Dorkygrin Dec 05 '10 at 20:10
  • @Dorkygrin - do you the `import` line from the top of the script exactly as it is in my example? The `datetime` module contains the `datetime` class which can be confusing. In other words `import datetime` does something very different from `from datetime import datetime`. The first binds the module to the name `datetime` and the second binds the class to the name. – David Webb Dec 05 '10 at 20:25
  • I tried it like in your example. And I tried 'import datetime'. Both give the same error. Works OK using IDLE. Something goofy in the program I'm writing it for. – Dorkygrin Dec 05 '10 at 21:42
  • Just found out that I have to use the statement 'global datetime' in order to declare the class. Did that and it took care of the error. Now getting an error about off_windows not defined. Hummm.... – Dorkygrin Dec 06 '10 at 17:18
  • Anyone know how I define "off_windows" as it is used in the code Dave Webb posted? Thanks !!! – Dorkygrin Dec 06 '10 at 21:30
  • The actual statement that I get in the error log is "global name 'off_windows' is not defined. Seems like python thinks this dictionary index should be a defined global variable. Confusing! – Dorkygrin Dec 07 '10 at 01:39
  • @Dorkygrin The code as it is should define `off_windows`. Is is possible you're running the function before you get to the line where off_windows is defined? – David Webb Dec 07 '10 at 11:16
  • Not possible, I'm running it mostly as you suggested. It works beautifully outside of the program that accepts Python code. Must have something to do with they way that program handles Python. It's beyond me, I've kicked it out to the base programmers. – Dorkygrin Dec 07 '10 at 13:57