in reply to Increment through date range by day with only standard modules.

General approach I'd use: Use Time::Local and localtime to alternate between epoc time and a more standard time format. (Add days in epoc time, convert to standard, use, then convert back to epoc at a specific time of day and start over.)

I'll leave the actual code as an exercise. ;)

use Time::Local; my $date_epoc = timelocal(0,0,12,23,11,2007); my $end_date = timelocal(0,0,12,12,4,2008); my @date_array; push @date_array, '2008-11-23'; while ( $date_epoc < $end_date ) { # Might want <= instead: I'd have +to check. $date_epoc = $date_epoc + 86400; my (undef, undef, undef, $day, $mon, $year) = localtime($date_epoc) +; push @date_array, "$year-$mon-$day"; $date_epoc = timelocal(0,0,12,$day,$mon,$year); }
  • Comment on Re: Increment through date range by day with only standard modules.
  • Download Code

Replies are listed 'Best First'.
Re^2: Increment through date range by day with only standard modules.
by ikegami (Patriarch) on Dec 12, 2008 at 20:26 UTC
    • You have an off-by-one error for the months.
    • The last line of your loop is a no-op.
    • @date_array is redundant.
    • A C-style for loop works great here.
    • strftime is most appropriate here.
    • 86400 is better written as 24*60*60. The latter is self-documenting.
    • I prefer to use timegm/gmtime instead of setting the time to noon.
    use strict; use warnings; use POSIX qw( strftime ); use Time::Local qw( timegm ); my ($y1,$m1,$d1) = (2007,23,11); my ($y2,$m2,$d2) = (2007, 4,12); my $date1 = timegm(0,0,0,$d1,$m1-1,$y1); my $date2 = timegm(0,0,0,$d2,$m2-1,$y2); my @dates; for (my $date=$date1; $date<=$date2; $date+=24*60*60) { push @dates, strftime('%Y-%m-%d', gmtime($date)); }
      1. Yes, I do. My Bad.
      2. No, it's not. It's actually vitally important: It handles daylight savings time, leap seconds, and other time oddities, by ignoring them and resetting things.
      3. Yes, it does. I just never think of them...
      4. strftime is nice, but since you need to separate the info out anyway, I figured we might as well leave it off.
      5. Good point.
      6. Again: The setting to noon helps make sure you don't have to worry about the oddities in computing time. (It's less likely to make a difference at noon.) I don't care what timezone you are in, just make sure you aren't using midnight, as you'll get errors!

        No, it's not. It's actually vitally important: It handles daylight savings time, leap seconds, and other time oddities, by ignoring them and resetting things.

        You're right that it's not quite a no-op. It changes the hour to 12 if it's 11 or 13.

        You're wrong about it being vitally important. Quite the opposite, it's of no consequence. You'll never be off noon by more than an hour.

        strftime is nice, but since you need to separate the info out anyway, I figured we might as well leave it off.

        No you don't have to "separate the info out". Not into variables, at least. It keeps the code compact. That's what makes it nice.

        I don't care what timezone you are in, just make sure you aren't using midnight, as you'll get errors!

        You missed the entire point. If you use timegm+gmtime, you don't have to make sure you aren't using midnight. You won't get errors.

      Thanks, I will look over this tonight. You both have been very helpful.
Re^2: Increment through date range by day with only standard modules.
by dbmathis (Scribe) on Dec 12, 2008 at 19:59 UTC
    Thanks, this approach makes sense. Thanks!