[Tutor] Re: Could I have used time or datetime modules here?

Brian van den Broek bvande at po-box.mcgill.ca
Tue Dec 7 16:50:49 CET 2004

Dick Moores said unto the world upon 2004-12-07 07:04:
> To Liam and Brian,


> Here's Brian's script in it's bare bones, without the input error 
> checking and his extensive and helpful comments:
> ===============begin code====================
> import datetime
> import time
> alarm_time = raw_input("Enter alarm time as hh:mm ")
> alarm_time_list = alarm_time.split(':')
> alarm_hour, alarm_minute = (int(alarm_time_list[0]),
>                             int(alarm_time_list[1]))
> now = datetime.datetime.now()
> alarm_datetime = datetime.datetime(now.year+4, now.month, now.day,
>                                    alarm_hour, alarm_minute)
> print alarm_datetime
> alarm_in_seconds = (alarm_datetime - now).seconds
> print "I should wake up in %d seconds" % alarm_in_seconds
> time.sleep(alarm_in_seconds)
> print "I'm awake!"
> ================end code=====================


> Brian, where did you learn about the ".seconds". And the .year, .month, 
> .day of
> "alarm_datetime = datetime.datetime(now.year + 4, now.month, now.day,
>                                    alarm_hour, alarm_minute)"?
> Does this come from a general knowledge of OOP, or is it somewhere in 
> the Python docs? The only thing I've seen, and it's not an explanation, 
> is in note (1) on http://docs.python.org/lib/datetime-date.html

Oh Sir, you flatter me! My general knowledge of OOP is about the same as 
my general knowledge of the migration patterns of Siberian water-fowl. ;-)

After Anna, Gonçalo, and Liam encouraged me to explore the datetime 
module, I read (OK, skimmed) the docs. For my original purpose, I just 
needed to test two times with '>', but I recalled something about 
timedelta objects being returned by subtracting one datetime from 
another. I hadn't used them before I wrote my script in reply to you. I 
learned about the handy for your purposes .seconds attribute in the 
Library Reference -- 6.10.2 timedelta Objects. (That's the section name 
in the 2.4 installed docs; I'm typing off line so can't [OK, won't] get 
a link.)

> It seems I've missed out on something important
> BTW I'm not sure you need the +4 of "now.year + 4". I've run this 
> without the +4 and it doesn't seem to be needed. And notes (1) and (4) 
> on that page seem to say this, as far as I understand them.

I'm not sure I do either :-)

Here's why I did it:

I discovered that in order to get the right "seconds until alarm" value 
from the datetime for now and the alarm datetime by subtracting one 
datetime object from another, I needed the alarm datetime to be in the 
future. But, since you can set an alarm for 09:00 tomorrow at 22:00 
today, I needed the alarm datetime to not use today's date. (If you use 
today's, you end up with seconds *since* 09:00 this morning, not the 
desired seconds *until* 09:00 tomorrow morning.) Since 
timedelta_object.seconds discards all difference save the seconds save 
those from the hours, minutes, and seconds difference in the two 
datetime objects, it doesn't matter what date the alarm datetime is set 
to. (The day information is in timedelta_object.days.)

Or, so I thought. I'd first tried getting the alarm datetime by simply 
taking the date component of datetime.datetime.now() and adding to the 
day value. That works fine, provided you are not on the last day of the 
month. But, when checking boundary cases before posting the code I sent, 
I discovered this sort of thing:

 >>> last_day_of_june = datetime.datetime(2004, 6, 30) # long for clarity
 >>> ldj = last_day_of_june                            # short for typing
 >>> new_day = datetime.datetime(ldj.year, ldj.month, ldj.day + 1)

Traceback (most recent call last):
   File "<pyshell#8>", line 1, in -toplevel-
     new_day = datetime.datetime(ldj.year, ldj.month, ldj.day + 1)
ValueError: day is out of range for month

So, adding to the day or the month was out, unless I wanted elaborate 
code to determine which to add to under what circumstances. So then I 
thought, "Well, just change from now.day + 1 to now.year + 1, and all 
problems go away". And then I thought "Ah, but what if I try to run the 
script on Feb. 29?

So, that's why I used now.year + 4. It still leaves open the possibility 
of getting bit by the every so often further correction to the calender, 
but, I *believe* the next one is due in 2100, so I think I can live with 
it. ;-)

I'm not saying it isn't hackish, though. Better ways surely exist.

Best to all,

Brian vdB

More information about the Tutor mailing list