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

Greetings, wizards!

I've a bit of a puzzler here: the comparison of file ages as returned by stat() vs those given by ls.

1. "ls -Flu" on a given file returns an access date of 08 July, 2004.
2. "ls -Flc" gives a modification date on that file of 08 July, 2004.
3. stat() on the same file gives atime = 1089270507, mtime = 1070566444.

The interesting thing is that when I use the lesser of the times returned by stat() to calculate an age, the following is the result:

$stat_age = (today (in e-seconds) - min( atime, mtime ) + 43200)/86400
= (1092168958 - 1070566444 + 43200)/ 86400
= 250

So what? Well, atime should correlate to access date, and mtime to modification date, right? So how come a file a bit more than a month old (the dates & times were acquired on 10 August), according to ls, shows up as being a bit over EIGHT months old according to stat()?

Most important: how can I determine *which* of these ages is correct? I'm trying to create a file aging report to determine which files haven't been touched for a certain period of time. I have to know that I'm getting accurate INPUT if I want to have any hope of accurate OUTPUT--I'm trying to avoid a GIGO situation here. Any help in the resolution of this dilemma would be appreciated.

Thanks!

Replies are listed 'Best First'.
Re: ls dates vs stat() ages
by bluto (Curate) on Sep 27, 2004 at 18:29 UTC
    Note "ls -Flc" appears to give ctime, not "modification time" mtime. It's actual usage varies greatly depending on your OS and is generally when the file's *status* changes, not the file data itself. See perldoc -f stat and especially "perldoc perlport" and then look for 'ctime' in the stat entry. Generally, atime >= mtime since it is the last access time or the modification time, whichever is more recent.

    FWIW, depending on what you are trying to do, it may be impossible to guarantee that mtime/atime/ctime will be usefull. For example if users can touch files with arbitrary dates (e.g. using touch or "tar -xf" to dearchive a tree), then you have no real way of determining age based on atime or mtime (and perhaps ctime).

      Hey, Bluto, Thanks for the answer. I've had several responses explaining how I've misinterpreted, mishandled, and/or misused the data returned by stat(). Maybe I'll revisit it.

      OTOH, things on the "ls" front keep getting more and more confusing. I've been using ls with the -u flag for "access time" and the -c flag for "modification time."

      Now it seems that what I *might* want is the default time returned by ls without any date-related flag because the -c flag hooks things like chmod, chown, etc., while the default hooks only changes to the file's data. Hmmm.....

      Thanks again!
Re: ls dates vs stat() ages
by ikegami (Patriarch) on Sep 27, 2004 at 17:57 UTC
    Maybe you're getting the ctime by accident? stat works fine for me:
    atime: >perl -le "print(scalar(localtime((stat('somefile'))[8])));" Mon Sep 27 12:06:06 2004 mtime: >perl -le "print(scalar(localtime((stat('somefile'))[9])));" Fri Sep 24 18:39:39 2004 ctime: >perl -le "print(scalar(localtime((stat('somefile'))[10])));" Tue Dec 16 17:17:50 2003

    Or maybe you are using stat on link? Compare stat vs lstat.