Tuesday, July 29, 2008

How To Parse Timestamp

Whenever I am 'free' (am I always free? I am not going to tell you :-), I will visit UNIX.com shell programming forum and find some challenging tasks to solve. One of the questions posted today is: how to calculate the time difference between two timestamps.

Very often people "echo" date format to log file at the beginning and end in a shell script and the output will be stored in a log file. Suppose you are given the below output, how do you work out the elapsed time:
Oracle Q03 Begin Hot BACKUP Time: 07/23/08 18:35:46
Oracle Q03 End Hot BACKUP Time: 07/24/08 14:18:15

I know it is trivial to convert the timestamps to epoch in Tcl. How about other scripting languages such as Perl and Python

Let's find out.
Perl way:

#! /usr/bin/perl

use Time::Local;

while (<>) {
 if ( /(\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d):(\d\d)$/ ) {
  $yr=$3+2000; $mth=$1; $day=$2;
  $hh=$4; $mm=$5; $ss=$6;

  if (/Begin Hot BACKUP/) {
   $t0=timelocal($ss,$mm,$hh,$day,$mth,$year);
  }
  if (/End Hot BACKUP/) {
   $t1=timelocal($ss,$mm,$hh,$day,$mth,$year);
  }
 }
}
print $t1-$t0,"\n";

Python way:

#! /usr/bin/python

import sys
import re
import datetime
import time

for newline in sys.stdin.readlines():
 line=newline.rstrip()
 t=re.findall('(\d\d)/(\d\d)/(\d\d) (\d\d):(\d\d):(\d\d)$',line)
 ts=t[0]
 if t:
  if 'Begin Hot BACKUP' in line:
   _t=datetime.datetime(int(ts[2])+2000, int(ts[0]), int(ts[1]), int(ts[3]), int(ts[4]), int(ts[5]))
   t0=int(time.mktime(_t.timetuple()))
  if 'End Hot BACKUP' in line:
   _t=datetime.datetime(int(ts[2])+2000, int(ts[0]), int(ts[1]), int(ts[3]), int(ts[4]), int(ts[5]))
   t1=int(time.mktime(_t.timetuple()))

print t1-t0

Tcl:

#! /usr/bin/tclsh

while { [gets stdin line] >= 0 } {
 if { [regexp {(\d\d/\d\d/\d\d \d\d:\d\d:\d\d)$} $line x ts] } {
  if { [string match {*Begin Hot BACKUP*} $line] } {
   set t0 [clock scan $ts]
  }
  if { [string match {*End Hot BACKUP*} $line] } {
   set t1 [clock scan $ts]
  }
 }
}
puts [expr $t1-$t0]

UNIX shell script way:

#! /bin/sh

: NO WAY!! Let me know if you have the solution simpler than above

In fact, you may want to consider working out the elapsed time in your original shell script. Here is the skeleton you may want to adopt:

#! /bin/sh
...
starttime=`perl -e 'print time()'`
...
# do you stuff
...
endtime=`perl -e 'print time()'`
...
echo "Elapsed time in seconds = `expr $endtime - $starttime`"

BTW, if you want sample codes as a reference, you should visit PLEAC (Programming Language Examples Alike Cookbook)

Labels: , ,

0 Comments:

Post a Comment

<< Home