prborg has asked for the wisdom of the Perl Monks concerning the following question:

I have the following code to copy some files from one place to another for post processing. Basically what it does get the current time and copies the files from the previous hour.
#!/usr/bin/perl $hr = (localtime(time))[2]; if ($hr == 0) { $hr = 23; @tdate = localtime(time - 86400); } else { $hr -= 1; @tdate = localtime(time); } $day = $tdate[3]; $mon = $tdate[4] + 1; $yr = $tdate[5] + 1900; $fname = sprintf("files.%4d%02d%02d%02d*.gz", $yr, $mon, $day, $hr); `cp /foo/$fname /bar/`;
Everything is working just fine. It grabs the date and everything, but my concern is how to handle Daylight Savings Time? When DST goes back 1 hr I'll end up processing the same files twice and when it moves forward 1 hr I'll end up skipping an hour of files. Any ideas will be appreciated. Thanks for your wisdom.

Replies are listed 'Best First'.
Re: date issues
by kennethk (Abbot) on Feb 20, 2009 at 17:50 UTC
    One choice would be to use gmtime in place of localtime - your file names would no longer be local time, but there's no issue with the time switch and everything would still be self consistent.
      Thanks! That should actually work. I'll have to adjust the hr to be -6 or something like that (otherwise I'll try to download files from the future), but that should work.
Re: date issues
by ikegami (Patriarch) on Feb 20, 2009 at 18:33 UTC

    I'm assuming these are log files to which data is appended based on local time.

    If so, forget the file name. It would makes more sense to move all but the newest file based on their modification time.

    my @log_files = ...[ read list of files from dir ]...; if (@log_files) { my $newest_idx = 0; my $newest_mtime = -M $log_files[0]; for my $idx (1..$#log_files) { my $mtime = -M $log_files[$idx]; next if $mtime < $newest_mtime; $newest_idx = $idx; $newest_mtime = $mtime; } # Leave newest alone. splice(@log_files, $newest_idx, 1, ()); } for my $log_file (@log_files) { ...[ process $log_file ]... }
    Hum, on second thought, this might be a bit more accurate:
    my @log_files = ...[ read list of files from dir ]...; if (@log_files) { my $newest_idx = 0; my $newest_name = $log_files[0]; for my $idx (1..$#log_files) { my $name = $log_files[$idx]; next if $name lt $newest_name; $newest_idx = $idx; $newest_name = $name; } # Leave newest alone. splice(@log_files, $newest_idx, 1, ()); } for my $log_file (@log_files) { ...[ process $log_file ]... }