Showing posts with label formatting. Show all posts
Showing posts with label formatting. Show all posts

Monday, April 5, 2010

Converting “YYYYMMDDHHMMSS” Dates

Sometimes you end up dealing with date values which are in the form of “YYYYMMDDHHMMSS:00000-GMT” (where “GMT” is a multiple of hours * 60 deviation from Greenwich Mean Time).  Formatting those into usable date values can be done several ways.  This is just one way.  And I threw in a somewhat not-so-obvious KiXtart version of this function for the hell of it.

VBScript version

Function mDate(strDate, format)
Dim tmp, retval
On Error Resume Next
Select Case Lcase(format)
Case "short":
tmp = Mid(strDate, 5, 2) & "/" & _
Mid(strDate, 7, 2) & "/" & _
Left(strDate,4)
retval = FormatDateTime(tmp, vbShortDate)
Case "datetime":
tmp = Mid(strDate, 5, 2) & "/" & _
Mid(strDate, 7, 2) & "/" & _
Left(strDate,4) & " " & _
Mid(strDate, 9, 2) & ":" & _
Mid(strDate, 11, 2) & ":" & _
Mid(strDate, 13, 2)
retval = FormatDateTime(tmp, vbShortDate) & " " & _
FormatDateTime(tmp, vbLongTime)
Case "long":
tmp = Mid(strDate, 5, 2) & "/" & _
Mid(strDate, 7, 2) & "/" & _
Left(strDate,4) & " " & _
Mid(strDate, 9, 2) & ":" & _
Mid(strDate, 11, 2) & ":" & _
Mid(strDate, 13, 2)
retval = FormatDateTime(tmp, vbLongDate)
End Select
mDate = retval
End Function


wscript.echo mDate("20100305132705.00000-520", "short")
wscript.echo mDate("20100305132705.00000-520", "long")
wscript.echo mDate("20100305132705.00000-520", "datetime")


KiXtart Version



Function FormatDateTime($v, $f)
Dim $sc, $result
$sc = CreateObject("ScriptControl")
$sc.Language = "vbscript"
$result = $sc.Eval('FormatDateTime("'+$v+'",'+$f+')')
$sc = 0
$FormatDateTime = $result
EndFunction

Function mDate($strDate, $format)
Dim $tmp, $retval
Select
Case $format = "short"
$tmp = Substr($strDate, 5, 2) + "/" +
Substr($strDate, 7, 2) + "/" +
Left($strDate,4)
$retval = $tmp
Case Lcase($format) = "datetime"
$tmp = Substr($strDate, 5, 2) + "/" +
Substr($strDate, 7, 2) + "/" +
Left($strDate,4) + " " +
Substr($strDate, 9, 2) + ":" +
Substr($strDate, 11, 2) + ":" +
Substr($strDate, 13, 2)
$retval = $tmp
Case Lcase($format) = "long"
$tmp = Substr($strDate, 5, 2) + "/" +
Substr($strDate, 7, 2) + "/" +
Left($strDate,4)
$tmp = FormatDateTime($tmp, "vbLongDate")
$retval = $tmp
EndSelect
$mDate = $retval
EndFunction


? mDate("20100305132705.00000-520", "short")
? mDate("20100305132705.00000-520", "long")
? mDate("20100305132705.00000-520", "datetime")


Yes, the KiXtart version is somewhat “cheating” but who cares.  It works, and it saves me a little bit of coding.  The performance overhead delta is near-zero, unless you’re running on 1990’s hardware.

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.

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

(vbscript)
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"
Else
$sfx = "PM"
EndIf
$Now1 = $today+" "+Int($hour)+":"+$min+":"+$sec+" "+$sfx
EndFunction

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

? "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”
Else
$Now1 = $today+" "+Int($arrTime[0])+":"+$arrTime[1]+":"+
$arrTime[2]+" PM”
EndIf
EndFunction


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.

Sunday, July 5, 2009

KiXtart: ScriptControl VBScript to Outsource Expressions


Function DaysOld($date)
Dim $sc, $result
$sc = CreateObject("ScriptControl")
$sc.Language = "vbscript"
$result = $sc.Eval("DateDiff("+Chr(34)+"d"+Chr(34)+", "+Chr(34)+$date+Chr(34)+", Now)")
$sc = 0
$DaysOld = $result
EndFunction

Function FormatDateTime($strDate, $format)
Dim $sc, $result
$sc = CreateObject("ScriptControl")
$sc.Language = "vbscript"
$result = $sc.Eval("FormatDateTime("+Chr(34)+$strDate+Chr(34)+","+$format+")")
$sc = 0
$FormatDateTime = $result
EndFunction


Test examples:

$testvalue = '2009/01/03 12:34:56'

$test1 = FormatDateTime($testvalue, 'vbShortDate')
$test2 = FormatDateTime($testvalue, 'vbLongDate')
$test3 = FormatDateTime($testvalue, 'vbLongTime')

? "shortdate: $test1"
? "longdate: $test2"
? "longtime: $test3"

$test4 = DaysOld($testvalue)
? "days old: $test4"

Friday, July 3, 2009

VBScript / ASP String Padding


Function PadString(strval, delim, length, side)
Dim tmp : tmp = Trim(strval)
Select Case Ucase(Left(side,1))
Case "L":
Do While Len(tmp) < length
tmp = delim & tmp
Loop
Case "R":
Do While Len(tmp) < length
tmp = tmp & delim
Loop
End Select
PadString = tmp
End Function

VBScript / ASP Date Formatter Function



Function FDate(dateval, mode)
Select Case mode
Case "MM/DD/YYYY":
FDate = FormatDateTime(dateval, vbShortDate)
Case "YYYY-MM-DD":
FDate = Year(dateval) & "-" & _
PadString(Month(dateval), "0", 2, "Left") & "-" & _
PadString(Day(dateval), "0", 2, "Left")
Case "Mmm D, YYYY":
FDate = FormatDateTime(dateval, vbLongDate)
Case "Mmm D, YYYY HH:MM:SS":
FDate = FormatDateTime(dateval, vbLongDate) & " " & FormatDateTime(dateval, vbLongTime)
Case "MM/DD":
FDate = Month(dateval) & "/" & Day(dateval)
Case "Mmm DD":
FDate = MonthName(Month(dateval), True) & " " & Day(dateval)
Case "MMM DD":
FDate = MonthName(Month(dateval), False) & " " & Day(dateval)
Case Else:
FDate = "[FDate] invalid option parameter specified"
End Select
End Function