>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

Reply via email to