Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Finding the dates for the reminder mail system

by d-evil (Novice)
on Nov 08, 2008 at 20:04 UTC ( #722430=perlquestion: print w/replies, xml ) Need Help??

d-evil has asked for the wisdom of the Perl Monks concerning the following question:


I am trying a reminder mail system in perl, which automatically sends reminder mails to the responsible persons whoever not completed the task on time... I have the mail system in place and i am in need of logic to find the dates.

In nutshell, my requirement is, I have a due date for a particular task and i need to start sending reminder mails on WED and FRI of the two weeks previous to the due date. ie. If the due date is Dec 15 2008, i need to send mails on wed and fri from Dec 8 2008. And also while sending the last reminder mail ie. Dec 12 2008(Fri), i need to copy the mail to a higher level person as well.

Since the day of the due date varies, i cant able to find the correct way of finding when the last mail should be sent. I have gone through Date::Calc and Date::Manip modules and i am using ParseDate, Delta_Days and UnixDate subroutines, but still i was not able to grasp the correct logic?
Any help on this?

  • Comment on Finding the dates for the reminder mail system

Replies are listed 'Best First'.
Re: Finding the dates for the reminder mail system
by eighty-one (Curate) on Nov 08, 2008 at 20:44 UTC
    So, to sum up, you want to . . .
    1. Have your script find the day of the week today
    2. If it's a Wed or Fri, query your db and find all projects due today+14 days into the future or sooner. Else, end the script
    3. Foreach of those, see if there is another Wed or Fri between now and the due date. If so, send a reminder. If not, send a reminder and a notice to management.

    If you haven't already, look at The Many Dates and Times of Perl.

    I prefer to work with epoch time when doing calculations, and convert back to other formats for db queries or display.

    I would get the epoch time, then find the day of the week with Date::Day. Adding 14*24*60*60 to the current epoch time give you the epoch time two weeks from now (since epoch is in seconds, convert 14 days to hours then minutes then seconds to find that, thus 14*24*60*60). I assume you're using a databse to store projects, so just query for all projects due BETWEEN those two dates, after having converted them into a format the db likes.

      Your link is broken. Try The Many Dates and Times of Perl. Your suggestion to read this article is spot on. It is definitely worth reading.

      You've got to be careful doing epoch calculations. What happens over daylight savings time shifts? You can have a 23 or 25 hour day. Depending on the time you run your script you can wind up with the wrong date. There are other opportunities for errors as well.

      In most cases, you are better off using a library like DateTime (my personal favorite) to handle these calculations. Other options are mentioned in the article you suggested.

      To get a date two weeks from now with DateTime simply write:

      my $due_date = DateTime->now->add( weeks => 2 );

      That seems easier to understand than adding 2*7*24*60*60. It also is less likely to generate an error.

      TGI says moo

Re: Finding the dates for the reminder mail system
by ikegami (Patriarch) on Nov 08, 2008 at 20:33 UTC

    Isn't this as simple as running the script every Wed and Fri (say as a cron job), and sending an email for every due date that's [0..14] (or [1..14]*) days away from today?

    For the last reminder,
    On Wednesdays, check if the due date is [1..2] (or [0..1]**) days away from today.
    On Fridays, check if the due date is [1..5] (or [0..4]**) days away from today.

    * — If you don't want notifications on the due date.
    ** — If you want the special notification be to sent before the due date.

    Update: Untested code:

    use Date::Calc qw( Day_of_Week Delta_Days Today ); use List::Util qw( min ); my ($ty,$tm,$td) = Today(); for (...{ tasks }...) { my ($dy,$dm,$dd) = ...{ due date of task }...; my $delta = Delta_Days($ty,$tm,$td, $dy,$dm,$dd); next if $delta < 0; # Don't care about past-due tasks. next if $delta > 14; # Don't care about due dates that far ahead. my $ddow = Day_of_Week($dy,$dm,$dd); # $cc_super is true if this is the last # Wednesday or Friday before the due date. my $days_to_wed = (3 - $ddow) % 7; my $days_to_fri = (5 - $ddow) % 7; my $days_to_next = min $days_to_wed, $days_to_fri; my $cc_super = ( $delta > 0 && $delta <= $days_to_next ); send_reminder($cc_super, ...); }

    Update: Fixed typo in code resulting in the error mentioned in reply.

      hi ikegami,

      the code for finding the last wednesday or friday does not work for the following scenario

      due_date = Dec 15 2008 (Monday) Today_date = Dec 12 2008 (Friday) $delta = 3 $days_to_wed = 2, $days_to_fri = 4 $days_to_next = 2 $delta > 0 but $delta is not <= $days_to_next.
        Not using use strict; and use warnings; is bad enough. Asking why code doesn't work without turning them on and fixing the errors is even worse. It would have immediately pointed out why $days_to_wed and $days_to_fri contain the wrong values.
Re: Finding the dates for the reminder mail system
by tubaandy (Deacon) on Nov 10, 2008 at 20:30 UTC
    I've used Date::Manip for a similar (not the same) problem. From the documentation:
    "Miscellaneous other allowed formats are: which dofw in mmm in YY "first Sunday in June 1996 at 14:00" ** dofw week num YY "Sunday week 22 1995" ** which dofw YY "22nd Sunday at noon" ** dofw which week YY "Sunday 22nd week in 1996" ** next/last dofw "next Friday at noon" next/last week/month "next month" in num days/weeks/months "in 3 weeks at 12:00" num days/weeks/months later "3 weeks later" num days/weeks/months ago "3 weeks ago" dofw in num week "Friday in 2 weeks" in num weeks dofw "in 2 weeks on Friday" dofw num week ago "Friday 2 weeks ago" num week ago dofw "2 weeks ago Friday" last day in mmm in YY "last day of October" dofw "Friday" (Friday of current week) Nth "12th", "1st" (day of current month) epoch SECS seconds since the epoch (negative values are supported)."
    Per the author: "Date::Manip is written entirely in Perl. It's the most powerful of the date modules. It's also the biggest and slowest." I do like it a lot, as long as performance isn't an issue. All for what it's worth.


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://722430]
Approved by ikegami
Front-paged by Arunbear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2022-10-07 10:20 GMT
Find Nodes?
    Voting Booth?
    My preferred way to holiday/vacation is:

    Results (29 votes). Check out past polls.