Friday, August 26, 2011

Safari User Agent Detection in JavaScript

Here's a quick snippit for detecting if a browser is Safari version 4 or 5. It works for both desktop and mobile (iPhone, iPod, iPad) versions.

function detectSafari45()
  var safariRegEx = /Mozilla\/5\.0 \([^\)]*\) AppleWebKit\/\d+\.\d+(\.\d+)? \(KHTML, like Gecko\) Version\/[45]\.\d+\.\d+( Mobile\/\w*)? Safari\/\d+\.\d+(\.\d+)?/i
  var match = safariRegEx.exec(navigator.userAgent);

  if (match !== null && match.length > 0)
    return true;
  return false;

Tuesday, May 10, 2011

Averaging Timespans in T-SQL

I'm doing some work with an operations queue. All of the operations are added to a small table on our SQL Server instance. We have a start_datetime and a stop_datetime for each operation. It took me a little time but here's a select statement for profiling the wait times for operations in our queue.

  CONVERT(VARCHAR(13),creation_date,120) as [hour],
  CONVERT(VARCHAR(8), max(stop_datetime - start_datetime), 108) as MaxWaitTime,
  CONVERT(VARCHAR(8), min(stop_datetime - start_datetime), 108) as MinWaitTime,
  CONVERT(VARCHAR(8), cast(avg(cast(stop_datetime - start_datetime as float)) as datetime), 108) as AvgWaitTime
  start_datetime > '2011-05-07'
group by
  CONVERT(VARCHAR(13),start_datetime ,120)

Here are a few things to note.
This statement will spit out the min, max, and average running time for operations in the queue that start in the same hour.
The third argument for convert is pretty handy for DATETIMEs. Here is the page where it is described:
The AVG() function doesn't work for DATETIMEs, so we need to convert it to a float and then back again to get what we are looking for.

Here's the graph we ended up with.

Seems like it's time to invest in some more processing power.

Friday, April 22, 2011

Running Hudson from OS X: the Fiasco

It took me a while to figure this out and maybe it's just because I'm not a java guy, but I couldn't figure out how to start the Hudson continuous integration tool on my Mac. I downloaded the 2.0.0 version from the Hudson site ( The file was The instructions say to run

java -jar hudson-2.0.0.war

to start up the service. I unzipped the file and ended up with a bunch of .class files and no .war. Ah, looks like I also unzipped the .war file. So then I found this nice post ( on how to unzip a file without unzipping its contents. Now I have a


directory. I ran

$ java -jar hudson-2.0.0.war
Invalid or corrupt jarfile hudson-2.0.0.war

Hmm, not sure what to do next. Somewhere in my search I read that a .war is basically just a zip file. So I tried

$ java -jar

on the original file, which worked. I renamed

$ mv hudson-2.0.0.war

and I was off and running.

So I hope this helps some other java n00bs who may have run into this. The moral of the story is .war == .zip