Perl CGI time calculation

Any help would be appreciated.

I am displaying a summary of a user on the system using the 'last' command in the below format.
I am having difficulty with the 'Running Total' column where it keeps track of a running total
of the time logged in.


Login #            Date/Time                        Duration              Running Total
1         Mon Apr 11 18:24 - 18:27          00:03              Days, 0 hours, and 03 minutes
2         Sun Apr 10 18:42 - 21:31          02:49              Days, 2 hours, and 52 minutes
3         Sat Apr 9 14:19 - 14:33            00:13               Days, 3 hours, and  5 minutes
4         Wed Apr 6 21:58 - 22:26           00:28              Days, 3 hours, and 33 minutes
5          Wed Apr 6 20:18 - 21:56          01:38              Days, 4 hours, and 11 minutes
my @list = (`last | less`)

    Tr ( td({-style => 'width: 10%'},("Login #")), td({-style => 'width: 30%'},("Date/Time")),  td({-style => 'width: 10%'},("Duration")), td({-style => 'width: 50%'},("Running Total")) )
);

if ( my @input = grep /^\s*$user\b/, @list)
  {
       for ( my $i = 1; $i <= $#input; $i++ )
        {
 
   $input[$i] =~ /(\S+)\s+pts\/\S+\s+\S+\s+(\S+\s+\S+\s+\d+\s+\d+\:\d+\s+\S*\s+\S*\s*\w*)\(*(\d*)\:*(\d*)\)*/g;

print table
        (
                {-border=>0, width=>"55%"},
 Tr ( td({-style => 'width: 10%'},($i)), td({-style => 'width: 30%'},($2)),  td({-style => 'width: 10%'},($3.":".$4)) ,  td({-style => 'width: 50%'},( $0."Days, ".$0." hours, and ".0." minutes")))
        );
   }

Open in new window

fac66Asked:
Who is Participating?
 
wilcoxonConnect With a Mentor Commented:
I think this should work.  I also tweaked your regex slightly.
#!/usr/local/bin/perl

use strict;
use warnings;
use CGI qw(:standard);

my $user = 'somebody';

my @list = `last`;
#my @list = <DATA>;

print CGI->start_table({-border=>0, width=>'55%'}),
    Tr (td({-style => 'width: 10%'},"Login #"),
        td({-style => 'width: 30%'},"Date/Time"),
        td({-style => 'width: 10%'},"Duration"),
        td({-style => 'width: 50%'},"Running Total") ),
    "\n";

if ( my @input = grep /^\s*$user\b/, @list) {
    my @cum = (0, 0, 0);
    for (my $i = 0; $i < @input; $i++ ) {
 
        next unless ($input[$i] =~ /^\s*\S+\s+pts\/\S+\s+\S+\s+(\S+\s+\S+\s+\d+\s+\d+:\d+\s*\S*\s*\S*\s+)\(*(\d*)\:*(\d*)\)*/);

        my ($dt, $hr, $min) = ($1, $2, $3);
        add_dur(\@cum, $hr, $min);
        print 
            Tr (td({-style => 'width: 10%'}, $i),
                td({-style => 'width: 30%'}, $dt),
                td({-style => 'width: 10%'}, "$hr:$min"),
                td({-style => 'width: 50%'},
                    sprintf("%d days, %d hours, %d minutes", @cum) ) ),
            "\n";
    }
}

print CGI->end_table();

sub add_dur {
    my ($arr, $hr, $min) = @_;
    $arr->[2] += $min;
    while ($arr->[2] > 59) {
        $arr->[2] -= 60;
        $arr->[1]++;
    }
    $arr->[1] += $hr;
    while ($arr->[1] > 23) {
        $arr->[1] -= 24;
        $arr->[0]++;
    }
}

__DATA__
somebody   pts/93      1.2.3.4     Fri Mar 25 13:18 - 13:20  (00:02)
somebody   pts/94      1.2.3.5     Fri Mar 25 13:18 - 16:10  (00:52)
nobody   pts/94      1.2.3.5     Fri Mar 25 13:18 - 13:20  (00:00)

Open in new window

0
 
wilcoxonCommented:
Can you post the output of your 'last' command?  It does not appear to match what last outputs on my system (or else the "$input[$i] =~ /.../" has issues).
0
 
fac66Author Commented:
Running 'last|less' on my system:

nrisner  pts/0         81.213.156.102   Wed Apr 20 04:59 - 05:03  (00:04)
nrisner  pts/0         81.213.156.102   Wed Apr 20 04:44 - 04:49  (00:05)
bessler  pts/1        cm-204-193-202-2 Wed Apr 20 02:20 - 02:58  (00:37)
bessler  pts/1        cm-204-193-202-2 Wed Apr 20 01:29 - 01:59  (00:29)
kchin    pts/4          ip24-252-49-142. Wed Apr 20 00:36 - 00:39  (00:03)
kkrejci  pts/4           ip72-206-107-124 Wed Apr 20 00:25 - 00:30  (00:04)
nleonard pts/0        ip174-71-94-187. Tue Apr 19 23:59 - 02:37  (02:37)

I am back referencing for user ($1), date/time ($2), and broke up hour($3) & minute ($4)

 $input[$i] =~ /(\S+)\s+pts\/\S+\s+\S+\s+(\S+\s+\S+\s+\d+\s+\d+\:\d+\s+\S*\s+\S*\s*\w*)\(*(\d*)\:*(\d*)\)*/g;
0
 
fac66Author Commented:
Thanks again!!
Working perfect so far
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.