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

I am trying to write a program that stages files to later archive based off of either dates embedded in the filenames or if those don't exist then from the date of the mtime on the filesystem for each file.

Ok, so, that being said, I need the date to be as accurate as possible. However, after some tests I am finding that the mtime returned from stat() and then being converted to human readable format via Perl's built-in gmtime() that for some reason the month returned is one month off.

I find it more difficult to believe that there is something wrong with Perl versus something wrong with what I am doing. Please check my work and see if I am off somewhere.

First, I touch a file so I get the desired mtime that I am looking for. I check the mtime using a utility I wrote called macls. Here is the output...

MACtime for: "test_file_1_200008261030" Mode(-rw-r--r-- => 0644) gvc(2000) gvcadm(104) 0 bytes 0 blocks Modified time ........ Sat Aug 26 09:30:00 2000 Access time ........ Sat Aug 26 09:30:00 2000 Inode Change ........ Tue Jun 18 12:14:19 2002 ******************************************************* MACtime for: "test_file_2_199504231930" Mode(-rw-r--r-- => 0644) gvc(2000) gvcadm(104) 0 bytes 0 blocks Modified time ........ Sun Apr 23 18:30:00 1995 Access time ........ Sun Apr 23 18:30:00 1995 Inode Change ........ Tue Jun 18 12:14:39 2002 ******************************************************* MACtime for: "test_file_3_200506200200" Mode(-rw-r--r-- => 0644) gvc(2000) gvcadm(104) 0 bytes 0 blocks Modified time ........ Mon Jun 20 01:00:00 2005 Access time ........ Mon Jun 20 01:00:00 2005 Inode Change ........ Tue Jun 18 12:15:00 2002 Total files checked : 4 Total size in bytes : 0 Total size in Kbytes: 0K
Note the strange and abnormal dates how they jump around and stuff =P jk. Anyway, so we know the dates are on the file system the way I want them. Oh, also note that the time stamp I used for the touch command is in the filename so I can reference it should the mtime get whacked in the moving of the files from place to place on the fs. One thing I just noticed is the actual time I specified for the touch command is off by one hour on the file system. Very interesting.

Ok. Now, I now do the following:

perl -e 'open(F,"test_file_1_200008261030");$date = (stat(F))[9];@date + = (eval((gmtime($date))[3,4,5]));print "@date\n"' 26 7 100
For everyone who doesn't know, the first number is the day, the second number is the month and the third number is the year - 1900. Everything is fine except the month value. Its off by a month.

What am I overlooking?

_ _ _ _ _ _ _ _ _ _
- Jim
Insert clever comment here...

Replies are listed 'Best First'.
Re: built-in gmtime() returning one month off?
by belg4mit (Prior) on Jun 18, 2002 at 19:03 UTC
    gmtime, the range is 0-11

    --
    perl -pew "s/\b;([mnst])/'$1/g"

Re: built-in gmtime() returning one month off?
by insensate (Hermit) on Jun 18, 2002 at 19:07 UTC
    The localtime and gmtime functions represent the month of the year as a digit between 0 and 11 (0 = January etc...). Add one to your month value to get the result you are looking for.
    ($day,$month,$year)=(gmtime)[3,4,5]; printf"02d-%02d-%04d",$month+1,$day,$year+1900;
    -Jason
      Bah!! Somebody kick me please! :) Thanks to all. *sigh*

      _ _ _ _ _ _ _ _ _ _
      - Jim
      Insert clever comment here...

        Bah!! Somebody kick me please! :) Thanks to all. *sigh*

        /me kicks snafu :)
        Next time, RTFM first. On your local system, you can use perldoc -f gmtime to get the appropriate documentation. Don't code by trial-and-error. Always have a terminal open to access documentation :)

        - Yes, I reinvent wheels.
        - Spam: Visit eurotraQ.
        

Re: built-in gmtime() returning one month off?
by grinder (Bishop) on Jun 18, 2002 at 19:32 UTC
    So far the other responses have all given correct advice, however, you may still be wondering about the reason months are off by one.

    The reason the value is as it is is so that you may use it to index an array of month names, without wasting the first element. Thus, you could get the month name with something like:

    my $month_name = (qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/)[$month];

    There is some method to the madness...


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
Re: built-in gmtime() returning one month off?
by thelenm (Vicar) on Jun 18, 2002 at 19:08 UTC
    It may just be that the month returned by gmtime is zero-based, so you'll need to add 1 to get the value you expect (e.g., 1 for January, etc.)

    -- Mike

    --
    just,my${.02}

Re: built-in gmtime() returning one month off?
by Abigail-II (Bishop) on Jun 19, 2002 at 13:16 UTC
    What am I overlooking?
    The documentation that comes with Perl? It would have been a lot easier to type perldoc -f gmtime than to write your message.

    Abigail