in reply to Week Algorithm

I like this problem. Please take the following points as trying to be helpful, not as negative criticisms.

1. You say that the week "starts on Monday and ends on a Sunday" yet you provide an example which looks like Tuesday (8-19-03) through Monday (8-25-03). If you can better define what "last week" means, it would be easier to figure out if code met the spec. For example, is "today" ever part of "last week" or is it always the Mon-Sun that is completely before today?

2. You say you have "2 digits each for month, day and year" yet the examples you provide make it look like a single digit is accepted. Does the input you are trying to match have a leading zero for single digit months and days?

3. I don't think /^8\-[19-25]\-03/ does what you want it to. The character class in the middle (surrounded by square brackets) actually matches a single character of "1" or "9" through "5" or "5". The "9" through "5" is also going to be flagged as an invalid range since it starts with something higher than it ends.

4. You don't need to escape dashes (-) outside of character ranges.

5. If a regular expression is really the best approach, I think you are most likely going to end up with one that looks something like this:

$string =~ /^(7-26-03|7-27-03|7-28-03|7-29-03|7-30-03|7-31-03|8-1-03|8 +-2-03)/
This could be reduced by extrapolating the common portions, but you probably would not gain much and this format has the benefit that you can glance at it and know that it matches exactly the days you want.

6. Oh, yeah, I'd use Date::Manip to do the date calculations, but that's just because it's the only date manipulation package I've learned, it's portable (completely Perl), and it includes the kitchen sink. Be warned, though, that it's a bit tricky to understand the interface when you're starting out. Examples and testing help a lot.

-- Eric Hammond

Replies are listed 'Best First'.
Re: Re: Week Algorithm
by rupesh (Hermit) on Aug 25, 2003 at 07:35 UTC
    Hi,
    Based on your "points", including the fact that Ive been trying to simplify the way im going to handle the problem, I want to make some modifications:

    1. Last week is 6 days before the current day, including the current day (so you will have 7 days always).
    2. If the day/month has only 1 digit (eg. 1-9), there is no leading zeros. The year has a leading zero.

    Thanks for your feedback. I'll try Date::Manip. Though I had a look at Date::Calc that was suggested by 3Dan, it seems to be complicated too, and not a quick solution. Otherwise, it has a lot of features. The tricky part is to get the output from the module and put it in a regular exp.

    Did you ever notice that when you blow in a dog's face, it gets mad at you but when you take him on a car ride,he sticks his head out the window and likes it?

      Here is a lightly-tested solution using POSIX::mktime and localtime calculations based on your latest requirements. I make some assumptions about your data, so you may have to modify the splits to match your data correctly.

      use POSIX qw/mktime/; my ($dy, $mo, $yr) = (localtime)[3 .. 5]; $mo += 1; $yr = sprintf("%02d", $yr % 100); my $today = join '-', $mo, $dy, $yr; my $today_in_epoch = get_epoch_time($today); my $week_ago = $today_in_epoch - (60 * 60 * 24 * 6); # 6 days print "today is: $today\n"; while (<DATA>) { my ($date, undef) = split /,/; my $date_in_epoch = get_epoch_time($date); if ($date_in_epoch >= $week_ago && $date_in_epoch <= $today_in_epo +ch) { print "$date is in the last 6 days!!\n"; } } sub get_epoch_time { my $date = shift; my ($mo, $day, $year) = split /-/, $date; # notice we assume the year is 20XX return POSIX::mktime( 0, 0, 0, $day, $mo - 1, 100 + $year ); } __DATA__ 8-12-03,somename,someaddress....<br> 8-13-03,someothername,someaddress.... 8-20-03,foo,bar 8-18-03,blah,blah 8-19-03,blah,blah 08-25-03,blah,blah 8-30-03,future,date

      HTH

      --
      3dan