I prefer to initialise everything at the start, but that's just a preference thing I guess. Also, as previously suggested you should use %nick for readability purposes. You may one day forget what $2 is in the context of a whois reply, but you'll always know what %nick means smile

Code:
; Use: /idle <nickname>
ALIAS idle { ; by Raccoon 10-July-2013 13-aug-2013
  .raw WHOIS $$1 $1
  .enable #idle_whois
  hinc -mu5 idle_whois cnt 1
  .timerIDLE_WHOIS 1 5 .disable #idle_whois
}
#idle_whois off
RAW 319:*: { hadd -mu5 idle_whois $cid $+ $2 $+ .chans $hget(idle_whois,$cid $+ $2 $+ .chans) $3- | halt }
RAW 317:*: { hadd -mu5 idle_whois $cid $+ $2 $+ .idle $3-4 | halt }
RAW 318:*: { 
  VAR %PRECISION = 2, %nick = $2, %chans = $hget(idle_whois,$cid $+ $2 $+ .chans), %idles = $hget(idle_whois,$cid $+ $2 $+ .idle), $&
  %idle = $gettok(%idles,1,32), %signon = $gettok(%idles,2,32), %i = 1, %cidles, %rchans = %chans, %pchan, %chan, %cidles, %cidle, %chanidles
  if ($query(%nick)) { %cidles = $query(%nick).idle $+ :Query }
  if ($chat(%nick)) { %cidles = %cidles $chat(%nick).idle $+ :Chat }
  WHILE $gettok(%chans,%i,32) {
    %pchan = $v1
    %chan = $regsubex(%pchan,/^[^ $chantypes ]*/x,)
    %cidle = $nick(%chan,%nick).idle
    if (%cidle != $null) { 
      %cidles = %cidles %cidle $+ : $+ %pchan
      %rchans = $remtok(%rchans,%pchan,1,32)
    }
    inc %i
  }
  %cidles = $sorttok(%cidles,32,n)
  %i = 1
  %chanidles = 
  WHILE $gettok(%cidles,%i,32) {
    %pchan = $gettok($v1,2,58)
    %cidle = $gettok($v1,1,58)
    %chanidles = %chanidles %pchan $+ [[ $+ $dur(%cidle,%PRECISION) $+ ]]
    inc %i
  }
  echo -atic whois * %nick signed on $dur($calc($ctime - %signon),2) $+ , idle $dur(%idle,2) $+ , %chanidles %rchans
  hdel -w idle_whois $cid $+ %nick $+ .*
  hdec -m idle_whois cnt 1
  if (!$hget(idle_whois,cnt)) { .disable #idle_whois | hfree -w idle_whois }
  halt
}
RAW *:*: halt
#idle_whois end

;$duration(12345678) = 20wks 2days 21hrs 21mins 18secs / $dur(12345678) = 20w2d21h21m18s / $dur(12345678,2) = 20w2d
ALIAS dur { return $remove($gettok($regsubex($duration($1),/(\d+\w)\S*/g,\t),1- $+ $2,32),$chr(32)) } ; by Raccoon