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

In whole i am trying to write a script that when loaded saves the current time as a variable $time1 . Then prints out a quiz as a form with $time1 as a hidden value to be sent back to this script with a different function that when loaded now records $time2. And subtracts $time1 from $time2 to give the amount of time it took to complete the quiz.

I have found a few ways to have the current time displayed (printed) but I don't know of any that can be put into a variable in a format that can be added/subtracted. any help would be great!

Replies are listed 'Best First'.
Re: Current time as variable?
by bart (Canon) on Dec 10, 2003 at 18:39 UTC
    What's wrong with
    $time1 = time;
    ?

    If that's too coarse for you, you can try using Time::HiRes:

    use Time::HiRes 'time'; $time1 = time; sleep 2; $time2 = time; printf "Time difference = %.2f seconds\n", $time2-$time1;

      More on time:

      The time function gives you the number of seconds that passed since Jan 1, 1970. The number of seconds since 1/1/70 are also known as 'epoch seconds'.

      time is quite suitable/simple for calculating the passage of seconds.

      Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"
Re: Current time as variable?
by Omeron (Novice) on Dec 10, 2003 at 19:46 UTC
    In the part where you have the form, you could try
    print $cgi->hidden('time',time);
    then in the other part
    my $time=time-param('time');
    that gives you the number of seconds as a decimal. then you can do
    print $cgi->h2(sprintf("It took you %02d:%02d to take the quiz.",int($ +time/60),int($time%60)));
    Hope this helps.
Re: Current time as variable?
by hanenkamp (Pilgrim) on Dec 10, 2003 at 20:01 UTC

    I don't know what the purpose of the timer is, but I thought I'd let you know of a potential risk factor if it is important that it not be faked. If you place the initial time in a hidden form variable a clever individual should be able to fake their test time.

    A better solution might be to use something like CGI::Session to store the initial time on the server and a session id on the client via your hidden form variable (or in a cookie or URL) to make certain that the timer is not abused.

      This is the way I've always done it.
      my $start = time; #do your work/quiz/etc. my $end = time; my $time_taken = $end-$start; print "Quiz/Work/Etc... took".$time_taken." seconds\n";
      You can take the resultant epoch seconds and split them out into hours and minutes using some basic math.

      Grygonos
Re: Current time as variable?
by talexb (Chancellor) on Dec 10, 2003 at 18:30 UTC

    Maybe I'm missing something, but why don't you just save the time as epoch seconds instead of some type of YYMMDD HHMMSS format. Then subtracting to find the net time is a snap.

    --t. alex
    Life is short: get busy!
Re: Current time as variable?
by jZed (Prior) on Dec 10, 2003 at 18:31 UTC
    Time::Local is probably what you want (presuming you don't need subsecond accuracy). This should print "10" because it sleeps for 10 seconds.
    use Time::Local; my @now = localtime(); my $epoch_time1 = timelocal(@now); sleep 10; @now = localtime(); $epoch_time2 = timelocal(@now); print $epoch_time2 - $epoch_time1;
    Update: perldoc -f time :-). My example is just something to play with to show the differences between the available time representations.
Re: Current time as variable?
by Plankton (Vicar) on Dec 10, 2003 at 18:34 UTC
    CPAN has Date::Calc. Have you tried that?

    Plankton: 1% Evil, 99% Hot Gas.
Re: Current time as variable?
by Limbic~Region (Chancellor) on Dec 11, 2003 at 00:05 UTC
    einerwitzen,
    As been pointed out, the basic idea is:
    my $start = time; # Quiz is taken my $end = time; my $elapsed = $end - $start;
    The result will be in the total number of elapsed seconds. The only thing I would add is how to convert that into plain english. There are a handful of modules that can do that. I took a crack at it myself as a learning experience, but I also reference the other modules if you want to use something that is supported.

    Cheers - L~R

      it seems that they all work when the codes you gave are in one part. I tried it as

      &starttime; &stoptime; sub starttime{ my $start = time; sleep 5; } sub stoptime{ my $end = time; my $elapsed = $end - $start; print $elapsed; }
      and it always prints out as 1071679507 seconds
        That is because in sub stoptime, your script doesn't know what $start is, since you only declared that in the starttime sub. Now if you'd do it like the following, it would print out 5:
        my $start; my $end; &starttime; &stoptime; sub starttime{ $start = time; sleep 5; } sub stoptime{ $end = time; print $end - $start."\n"; }

        Update: If you'd put "use strict;" in the beginning of your little snippet, Perl would warn you about this with: Global symbol "$start" requires explicit package name at test line 14.

        --
        b10m