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

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

Could potentially receive more than one socket connection per second. Need to capture the exact date/time the connection is made because a file will be created with the date/combo as part of the filename. Here's what I've come up with so far, feel free to offer any improvements:
#!/usr/bin/perl -w use Time::HiRes qw(time); use strict; # using time from Time::HiRes to obtain fractions... my $now = time; my ($secs, $fract) = ($now =~ /(\d+)\.(\d+)/); # convert $secs to YYYYMMDDHHMMSS... my ($sec, $min, $hr, $day, $mon, $yr) = (localtime($secs))[0,1,2,3,4,5 +]; my $new = sprintf "%04d%02d%02d%02d%02d%02d", $yr + 1900, $mon + 1, $d +ay, $hr, $min, $sec; # combine the fraction from Time::HiRes::time to $new... print "Exact time is: $new$fract\n";
This works but seems like a hack. Is there a better way to do what I need?

Replies are listed 'Best First'.
Re: Obtaining The Exact Time
by sauoq (Abbot) on Oct 08, 2002 at 00:19 UTC
    Need to capture the exact date/time the connection is made because a file will be created with the date/combo as part of the filename.

    Using Time::HiRes to ensure unique filenames is probably overkill. It would be easier and cleaner to simply increment a counter for each connection created within the same second. I would use something like:

    { my ($t,$c); sub unique_timestamp { my $time = time; $c++; $c = 0 unless $time == $t; $t = $time; my ($s,$m,$h,$D,$M,$Y) = (localtime($time))[0..5]; sprintf "%04d%02d%02d%02d%02d%02d%03d", $Y+1900, $M+1, $D, $h, $m, $s, $c; } } # To see that work... for (1..100) { print unique_timestamp, "\n"; sleep rand 2; }

    If you could have more than 1000 connections in a second, you may wish to increase that %03d in the sprintf to %04d or something. This code avoids the use of a module and parsing out fractional seconds. It also results in sequential unique stamps that are the same length.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Obtaining The Exact Time
by Russ (Deacon) on Oct 08, 2002 at 00:08 UTC
    If you want a unique filename, combine the timestamp with the process ID of the fork handling the connection...

    Your question asks how to get the exact time, but I would be more worried about a guaranteed unique value.

    Russ
    Brainbench 'Most Valuable Professional' for Perl

    P.S. Look at POSIX::strftime. I think

    my $Now = strftime('%Y%m%d', localtime)
    is much prettier to use than
    ($sec, $min, ...) = (localtime())[0..5]; $Now = sprintf('%4d%2d%2d', $sec, $min...);

      I agree that he should be more concerned with a unique value.

      However, he didn't say that he was forking and, even if he is, he may well be handling some setup prior to the fork.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Obtaining The Exact Time
by Zaxo (Archbishop) on Oct 08, 2002 at 00:45 UTC

    POSIX strftime will help with formatting a string from the localtime($secs) call without all the extra variables. All you need is to give it a format string and the localtime call. The strftime man page details the format string conventions available.

    After Compline,
    Zaxo

Re: Obtaining The Exact Time
by fglock (Vicar) on Oct 08, 2002 at 00:15 UTC

    Date::Tie might help a bit with fractional times.

Re: Obtaining The Exact Time
by cacharbe (Curate) on Oct 08, 2002 at 12:23 UTC
    Just as a "Thinking Outside the Box" exercise, you can always get the time from the NIST, available from any and all of the mirrors mentioned here.
    use strict; my $host = '129.6.15.28'; my $port = '13'; my $sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'TCP'); die "Couldn't connect to $host on $port: $!\n" unless $sock; scalar <$sock>; my $time = scalar <$sock>; $sock->close; print $time."\n"; # $time has the format: #JJJJJ YR-MO-DA HH:MM:SS TT L H msADV UTC(NIST) OTM
    *shrug* It just happens to be something I'm working on for another project.

    C-.

    ---
    Flex the Geek