http://www.perlmonks.org?node_id=701157

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

I am using stat to get the timestamp of a file. The script I am running sits in a while loop until the timestamp of the file's hour and minute match the current hour and minute. Basically nothing happens in the script until it detects that a file was updated. I am using the command:
$stamp = ctime(stat($file)->mtime);
The problem is, the timestamp of the file is one hour off from the actual system time. It is very important that this returns the correct time, if it doesn't, all my actions will be delayed an hour! Is this a daylight savings or time zone issue with ctime()? Update: I checked the timestamp of the file using the GUI and noticed that it was off by an hour also, so maybe this is a different issue, one with the OS?

Replies are listed 'Best First'.
Re: Getting the timestamp of a file
by moritz (Cardinal) on Jul 30, 2008 at 15:36 UTC
    Usually there are no issues, because the return values are timestamps, which means they are numbers of seconds since start of the "epoch".

    The number of seconds since a particular time obviously is not dependent on daylight saving time. It should also not depend on your time zone, but since the system is responsible for keeping to track of the time, you have to trust it at some level.

Re: Getting the timestamp of a file
by jettero (Monsignor) on Jul 30, 2008 at 15:38 UTC

    I'm not as familiar with ctime, I always use localtime, so it'd be  $stamp = localtime( (stat $file)[9] ); I believe that will sort out the DST issues for you automatically.

    -Paul

      localtime( (stat $file)9 ) doesn't work for me. I get Wed Dec 31 18:00:00 instead of Wed Jul 30 10:47:00. Also, i use the local time module to build a time function to tell me what time it is, and anytime the use::localtime module is active and i use the localtime function i get errors.
        I suspect the time returned by localtime is correct and the time returned by whatever you think is doing it accurately is not. If it were purely a timezone issue it wouldn't be off by 47 minutes.

        -Paul

        $ ls -l monlog.txt -rw------- 1 h h 10755194 2008-05-30 12:59 monlog.txt $ perl -le 'print scalar localtime((stat)[9]) for @ARGV' monlog.txt Fri May 30 12:59:45 2008 $ perl -MFile::stat -le 'print scalar localtime(stat($_)->mtime) for @ +ARGV' monlog.txt Fri May 30 12:59:45 2008
        Worked pretty well here. What do you mean with "i use the local time module to build a time function to tell me what time it is, and anytime the use::localtime module is active and i use the localtime function i get errors"?? If you have a local "localtime.pm" module, change its name and the name of the "faux-localtime" function, because it's not good practice to clobber core functions' names.
        Update: used File::stat like becca23 did.
        []s, HTH, Massa (κς,πμ,πλ)
        localtime usually works pretty well. If it doesn't, chances are that you're doing something seriously wrong.

        But of course without seeing any code we can't tell.

Re: Getting the timestamp of a file
by broomduster (Priest) on Jul 30, 2008 at 15:58 UTC
    Another thing to check... Be sure the time zone ($ENV{TZ}) in the environment that your script is running in agrees with the OS.
Re: Getting the timestamp of a file
by RyuMaou (Deacon) on Jul 30, 2008 at 19:18 UTC
    If the timestamp of the file you're checking is off, try checking whatever makes that file. I'd bet it's either a different machine that's an hour off, or the file is being made at a different time than you think.

    Also, if it's consistently an hour off, you could just add it back in as part of the script! Kind of simplistic and it can cause other problems later if the timestamp gets corrected, but it may work for your purpose.
Re: Getting the timestamp of a file
by rir (Vicar) on Jul 30, 2008 at 21:08 UTC
    If you just want to process the file periodically when it has changed, you can:
    my $old_time = (stat( $file ))[9]; while ( 1 ) { sleep $period_in_seconds; my $current_time = (stat($file))[9]; while ( $current_time != $old_time ) { $old_time = $current_time; print "file changed$/"; $current_time = (stat($file))[9]; } }
    The above nods at the issue of race conditions; it ignores possible contention issues.

    Be well,
    rir