2013/02/03: Ever wondered, how much time you spent in front of the screen?

I recently did. To get a precise answer, I would have to keep some form of log of when I start sitting in front of my machine, and of when I leave or get interrupted. Doing so manually I know for sure I won't have the discipline. Where I, however, do have the discipline is to lock the screen whenever I stop staring at the screen for whatever reason. So that's a good point to measure. I keep daily records (hence I can clean up easily any files I don't want to draw any conclusions any more); to avoid any strange effects when staying up after midnight, I start logical days at 4am. So I changed the key binding for xlock to, additionally, execute

echo `gdate +%s` xlock >> $HOME/timelog/`gdate -d '4 hours ago' +%Y.%m.%d`
before calling xlock, and a corresponding unlock-entry afterwards; similar logs in my .xsession before and after the line running the window manager. (gdate is just the GNU variant of the date utility, usually called date on GNU/Linux systems.)

To sum up the time, I use the following script that deliberately ignores the activities over the change of the (logical) day. On the one hand, this (hopefully) is "I enjoy a relaxing time away from the machine" and, on the other hand, it is interesting to know the total time from the first to the last interaction with a computer on every day (providing, e.g., a lower bound on the time I spend awake). In fact, I have several screen-locking keys keeping track of which activity saved me from spending even more time in front of the machine.


#!/usr/bin/perl -w

my $path = $ENV{'HOME'} . "/timelog/";
my $logicalday = '4 hours ago';
my %times = ();

if (@ARGV == 0) {
  my $now = `gdate -d '$logicalday' +%Y.%m.%d`;
  doday($now, 1);
  dooutput();
} elsif ($ARGV[0] eq "week") {
  my $dow = `gdate -d '$logicalday' +%w`; chomp($dow);
  for (my $i = 0; $i <= $dow; $i++) {
    my $ago = $dow - $i;
    my $day = `gdate -d '$ago days ago $logicalday' +%Y.%m.%d`; chomp($day);
    if ($ago > 0) {
      doday($day, 0);
    } else {
      doday($day, 1);
    }
  }
  dooutput();
} elsif ($ARGV[0] eq "lastweek") {
  my $dow = `gdate -d '$logicalday' +%w`; chomp($dow);
  for (my $i = 7; $i > 0; $i--) {
    my $ago = $i + $dow;
    my $day = `gdate -d '$ago days ago $logicalday' +%Y.%m.%d`; chomp($day);
    doday($day, 0);
  }
  dooutput();
}


sub doday {
  my ($date, $istoday) = @_; chomp($date);
  open(my $file, "<", $path . $date) or return;

  my ($start, $current);
  foreach (<$file>) {
    my $line = $_; chomp($line);
    $line =~ /^([0-9]+) (.+)$/ or next;
    my ($time, $event) = ($1, $2);
    defined($start) and defined($current) and do {
      defined($times{$current}) or $times{$current} = 0;
      $times{$current} += $time - $start;
    };
    $start = $time;
    $current = $event;
  }
  $istoday and defined($start) and defined($current) and do {
    my $time = `gdate +%s`; chomp($time);
    defined($times{$current}) or $times{$current} = 0;
    $times{$current} += $time - $start;
  };
}

sub dooutput {
  foreach(sort(keys %times)) {
    printf "%-15s %5.1f h\n", $_, $times{$_} / 3600.0;
  }
}
download