Tuesday, March 2, 2010

Now vs Now: VBScript and KiXtart

Date values are a very common aspect to script writing and most any programming situation in general.  How dates are stored, presented and manipulated varies widely from one programming language to another.

Let’s look at the “Now” function included with Windows Scripting Host’s VBScript.  This function returns the current date and time in “mM/dD/YYYY hH:MM:SS XM” format.

In case you’re wondering what the hell “mM” and “hH” imply: they imply zero-trim numbers.  In other words 8:01:42 AM is not stored as 08:01:42 AM. The leading zero is omitted.  Same for month (“mM”), and day (“dD”) as well.

But KiXtart, one of my all-time favorite scripting languages, handles date values quite differently.  At first it may seem almost identical, but as you pick things apart you start to see the deltas.

? @date+" "+@time
>> 2010/03/02 08:20:01

Wscript.echo Now
>> 3/2/2010 8:20:01 AM

When you compare the output of each result above, not only are the order of YYYY/MM/DD flipped from M/D/YYYY, but the zero-trim is not used with KiXtart.  Is this “bad” or “wrong”?  No.  Just different.  There are times when this is actually a very handy benefit to have as the default.  But also notice that the time stamp is formatted differently.  And the AM/PM suffix is not shown.

So, how can we make KiXtart do it the way VBScript does it?  This is assuming you need to make it do that, of course, which you may not.  But this is for demonstration purposes, so cut me some slack - if you will.

Below are two examples for producing a VBScript formatted “Now” result.  The first one uses a rudimentary date->string parsing technique.  The second does a cop-out and simply knocks on the door of the ScriptControl COM interface to make VBScript do the work and hand back a result.  The performance overhead is about the same at this scalar load level.  If you start piling in a lot more, the results can shift the balance of performance in either direction, depending upon the nature of what your doing (math, string, date, or object management tasks).

Break ON

Function Now1()
$today = ""+@monthno+"/"+@mdayno+"/"+@year
$arrTime = Split(@time, ":")
$hour = $arrTime[0]
$min = $arrTime[1]
$sec = $arrTime[2]
If Int($hour) < 12
$sfx = "AM"
$sfx = "PM"
$Now1 = $today+" "+Int($hour)+":"+$min+":"+$sec+" "+$sfx

Function Now2()
Dim $sc, $result
$sc = CreateObject("ScriptControl")
$sc.Language = "vbscript"
$result = $sc.Eval('Now()')
$sc = 0
$Now2 = $result

? "Kix: "+Now1()
? "VBs: "+Now2()

The results should be identical.  Could I/you refactor the Now1() function to nest statements and further compact the code?  Sure.  Does it buy any performance gains? Not really.

Consider this variation…

Function Now1()
$today = ""+@monthno+"/"+@mdayno+"/"+@year
$arrTime = Split(@time, ":")
If Int($arrTime[0]) < 12
$Now1 = $today+" "+Int($arrTime[0])+":"+$arrTime[1]+":"+
$arrTime[2]+" AM”
$Now1 = $today+" "+Int($arrTime[0])+":"+$arrTime[1]+":"+
$arrTime[2]+" PM”

More compact for sure.  But there’s a hidden, even if trivial price: The repeated use of an array index request.  There are other ways to compact/refactor this of course, but for such few lines of code the pay-offs are difficult to justify beyond elegant coding form (aesthetics).  Oh well, blah blah blah.  What do I know anyway.  I just finished a huge “breakfast-for-dinner” and was then told my car repairs would cost way too much, so I’m blabbering to let off steam.  I hope you enjoyed this.

No comments:

Post a Comment