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

I am trying to create an error file when my process runs.
What I would like to do is to have the filename
equal “error” and today’s date. Can anybody point me in
the right direction?

Replies are listed 'Best First'.
Re: Date in Filename
by chip (Curate) on May 19, 2003 at 16:04 UTC
    Reading perldoc localtime will help you:

    my ($y,$m,$d) = (localtime)[5,4,3]; my $file = sprintf("errors.%04d-%02d-%02d", $y+1900, $m+1, $d); open ERRORS, '>>', $file;

        -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: Date in Filename
by halley (Prior) on May 19, 2003 at 16:10 UTC

    Whatever method you use, I recommend dates in the sortable format: "YYYY-MM-DD.hh-mm-ss".

    my @now = localtime(); my $timestamp = sprintf("%04d-%02d-%02d.%02d-%02d-%02d", $now[5]+1900, $now[4]+1, $now[3], $now[2], $now[1], $now[0]); my $filename = "error.$timestamp.log";

    --
    [ e d @ h a l l e y . c c ]

      I agree that dates should be in a sortable format.

      For filenames, I often use something like YYYYMMDD_HHMMSS-filename. It varies because sometimes I only need the date; sometimes I don't need seconds; etc.

      It doesn't much matter one way or the other, but I do think that, if human readablity is a goal, different separation characters for date components and time components are helpful. So, how about ISO 8601? YYYY-MM-DDTHH:MM:SS. Several CPAN modules already handle it...

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Date in Filename
by jdporter (Paladin) on May 19, 2003 at 16:06 UTC
    To get a useful short string from a date, I'd typically do something like this:
    my( $sec, $min, $hour, $mday, $mon, $year ) = gmtime; my $datestamp = sprintf "%04d%02d%02d-%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec;
    Then you could include that in a file name, and open STDERR to it:
    my $error_log = "error-$datestamp"; open STDERR, "> $error_log" or warn "Error redirecting stderr to $error_log: $!\n";
    Thereafter, all writes to stderr (including from warn and die) will go to that file.

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

      Why gmtime?

          -- Chip Salzenberg, Free-Floating Agent of Chaos

        There are various good reasons. One that I find compelling is that in this Internet Age, where I am and where my process runs might not be in the same timezone. Indeed, we might have many users in many timezones, and many servers in many timezones. I'm finding localtime to be rapidly diminishing in usefulness.

        jdporter
        The 6th Rule of Perl Club is -- There is no Rule #6.

        Maybe to avoid any ambiguity with DST? Otherwise, the error log could overwrite itself during the 'switching hour'.

        Cheers,Ben.

Re: Date in Filename
by Corion (Patriarch) on May 19, 2003 at 16:04 UTC
    Provided that your script name does not contain the percent sign :
    use strict; use POSIX; my $filename = strftime "$0.%Y%m%d-%H%M%S.log", localtime();
    strftime is a really cool function for timestamps, but documentation is scarce. The DateTime module has more/better documentation on the format strings than the stock Perl/POSIX documentation.
    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
      Tsk, passing unchecked data ($0) to strftime ... shame! What if somebody creates a symlink to the script, and that symlink's name contains a "%"; or what if there's a "%" in the path leading to the script? Then strftime is gonna get Really Mad, that's what.

          -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: Date in Filename
by cciulla (Friar) on May 19, 2003 at 16:10 UTC

    Try hitting "perldoc -f localtime".

    For example,

    use POSIX qw(strftime); $now_string = strftime "error%Y-%m-%d.txt", localtime; print "$now_string\n";

    Update: I gotta learn to type faster. :)

    Update: Noticed a bug.