>alarm_datetime = datetime.datetime(now.year, now.month, now.day, alarm_hour, alarm_minute)
Now that's clever. I too, have learnt a large amount from this thread. On Tue, 07 Dec 2004 23:57:59 -0500, Brian van den Broek <[EMAIL PROTECTED]> wrote: > Dick Moores said unto the world upon 2004-12-07 12:04: > > > > Brian van den Broek wrote at 07:50 12/7/2004: > > > >>> 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. > > > > > > Brian, > > > > I just can't succeed in reproducing the problems with the boundary > > cases with the +4 removed. I've tried setting my computer's clock to > > Nov 30, Feb 29, 2004, and Dec 31, 2004 (without changing the time). It's > > now about 9 am where I am, and setting the alarm time to 0700 (i.e., on > > the next day) works fine in all 3 cases. And of course no problem at > > today's date with setting the alarm time to 07:00. > > > > Isn't that what that note (1) on > > <http://docs.python.org/lib/datetime-date.html> implies? > > > > I did the testing with <http://www.rcblue.com/Python/timer4-ForWeb.py>, > > by remarking out the time.sleep() line and noting what the > > print_hms(sleepSeconds) function prints. > > > > Dick > > Hi Dick and all, > > I haven't checked your link yet, but thanks for it. (It's in the 'follow > when I've time' file.) > > I think this is all moot in light of Tim's post explaining: > > > > > Actually, you needed simpler code <wink>: > > > > > >>>>>>> import datetime > >>>>>>> ldj = datetime.datetime(2004, 6, 30) > >>>>>>> new_day = ldj + datetime.timedelta(days=1) > >>>>>>> print new_day > > > > 2004-07-01 00:00:00 > > Why I thought I needed it was that I was trying to do datetime's work > for it :-) > > I'd done: > alarm_datetime = datetime.datetime(now.year+4, now.month, now.day, > alarm_hour, alarm_minute) > > after trying: > alarm_datetime = datetime.datetime(now.year, now.month, now.day+1, > alarm_hour, alarm_minute) > > That did cause problems if the now datetime was the last day of a month > (see last_day_of_june example for proof). (If you aren't getting the > same problem is similar circumstances, well, I'm out of ideas on that one.) > > This was all to the end of constructing an alarm_datetime guaranteed to > be in the future from the user supplied alarm_hour, alarm_minute. > > On the bus today (great place for ideas, the bus ;-), I figured out I > could avoid the whole +4 because of leap years by doing something like > > alarm_datetime = datetime.datetime(now.year+1, 1, 1, > alarm_hour, alarm_minute) > > thus making the new datetime on Jan. 1 and skirting all month-end and > leap year issues. But, that is still a kludge, compared to Tim's way. > > In light of Tim's post (and without having thought about possible > further improvements to my approach given this new knowledge) I'd now do: > > >>> import datetime > >>> alarm_hour = 13 # skipping actual user > >>> alarm_minute = 25 # input part for ease > >>> now = datetime.datetime.now() > >>> alarm_datetime = datetime.datetime(now.year, now.month, now.day, > alarm_hour, alarm_minute) > >>> # I wouldn't be surprised if this can be done more smoothly. > >>> # It is likely residue of my original and wrong approach. > >>> # I will check and post back if I see the suspicion is right. > >>> # But, not before the weekend, I don't think. > >>> alarm_datetime = alarm_datetime + datetime.timedelta(days=1) > >>> print now > 2004-12-07 23:24:58.050000 > >>> print alarm_datetime > 2004-12-08 13:25:00 > >>> > > And, all is in order :-) > > (The worry that goes "But wait, what if I want my alarm later today, and > not tomorrow?" is what using .seconds is for: > > >>> alarm_in_seconds = (alarm_datetime - now).seconds > >>> alarm_in_seconds > 50401 > >>> _ / ( 60 * 60.0) > 14.000277777777777 > > Which is what's wanted, as the alarm_datetime is just a midge over 14 > hours ahead of the now datetime. The .seconds discards the difference in > days, and handles only the difference in seconds.) > > The note you reference: > > date2 is moved forward in time if timedelta.days > 0, or backward if > timedelta.days < 0. Afterward date2 - date1 == timedelta.days. > timedelta.seconds and timedelta.microseconds are ignored. OverflowError > is raised if date2.year would be smaller than MINYEAR or larger than > MAXYEAR. > > presupposes you are adding a timedelta to a datetime as in Tim's > suggestion. It makes no promises if you were doing something goofy like > I was. (If that is what you were trying to get me to see, sorry, but I > missed it.) > > I hope this clarifies things some :-) > > Thanks, Dick, Liam, and Tim. I've learned a good deal off this thread. > > > > Best to all, > > Brian vdB > > _______________________________________________ > Tutor maillist - [EMAIL PROTECTED] > http://mail.python.org/mailman/listinfo/tutor > -- 'There is only one basic human right, and that is to do as you damn well please. And with it comes the only basic human duty, to take the consequences. _______________________________________________ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor