Showing posts with label dates. Show all posts
Showing posts with label dates. Show all posts

Wednesday, August 27, 2014

Function: Get Maintenance Window Status (VBScript, ASP and PowerShell flavors)

A little function you can use to determine if a date/time window is active, pending or expired.  I've provided both PowerShell, VBScript and ASP examples (almost the same thing).

Note that PowerShell requires defining the function before invoking it, with regards to single-file, sequential ("top-down") processing order.

[powershell]
function Get-TimeWindowStatus {
    Param(
        [parameter(Mandatory=$true)]$Start,
        [parameter(Mandatory=$true)]$End
    )
    $now = Get-Date
    $dif1 = $(New-TimeSpan -Start $Start -End $now).Minutes
    $dif2 = $(New-TimeSpan -Start $End -End $now).Minutes
    if ($dif1 -lt 0) {
        return -1
    }
    elseif ($dif2 -gt 0) {
        return 1
    }
    else {
        return 0
    }
}

$d1 = "8/27/2014 9:30:00"
$d2 = "8/27/2014 10:00:00"

switch (Get-TimeWindowStatus -Start $d1 -End $d2) {
    -1 {write-host "Maintenance window has not begun."}
    1  {write-hsot "Maintenance window has expired."}
    default {Write-Host "Maintenance window is active."}
}
[/powershell]

ASP and VBScript on the other hand pre-process script code, so you can define functions anywhere within a given script file, and the location for invoking the function doesn't matter as long as it's in the same file (or loaded in advance using "#include" if using ASP).

[asp]
d1 = "8/26/2014 16:00"
d2 = "8/27/2014 9:00"

Select Case TIME_WINDOW_STATUS (d1, d2)
    Case 0:  Response.Write "Maintenance window is in effect."
    Case 1:  Response.Write "Maintenance window has expired."
    Case -1: Response.Write "Maintenance window has not begun."
End Select

Function TIME_WINDOW_STATUS (startDT, endDT)
    Dim dd1, dd2, result
    dd1 = DateDiff("n", d1, NOW)
    dd2 = DateDiff("n", d2, NOW)
    If dd1 > 0 And dd2 < 0 Then 
        result = 0
    ElseIf dd1 < 0 Then
        result = -1
    ElseIf dd2 > 0 Then
        result = 1
    End If
    TIME_WINDOW_STATUS = result
    End Function
[/asp]

[vbscript]
d1 = "8/26/2014 16:00"
d2 = "8/27/2014 9:00"

Select Case TIME_WINDOW_STATUS (d1, d2)
    Case 0:  wscript.echo "Maintenance window is in effect."
    Case 1:  wscript.echo "Maintenance window has expired."
    Case -1: wscript.echo "Maintenance window has not begun."
End Select

Function TIME_WINDOW_STATUS (startDT, endDT)
    Dim dd1, dd2, result
    dd1 = DateDiff("n", d1, NOW)
    dd2 = DateDiff("n", d2, NOW)
    If dd1 > 0 And dd2 < 0 Then 
        result = True
    ElseIf dd1 < 0 Then
        result = False
    ElseIf dd2 > 0 Then
        result = False
    End If
    TIME_WINDOW_STATUS = result
End Function
[/vbscript]

Wednesday, January 26, 2011

Recursively Delete Files by Extension Name

Const strExtensionsToDelete = "wav,avi,mp3,aac,tmp,bak"
Const testMode = True

Sub RecursiveDeleteByExtension(ByVal strDirectory, strExtensionsToDelete)
  Dim objFolder, objSubFolder, objFile
  Dim strExt
  Set objFolder = objFSO.GetFolder(strDirectory)
  For Each objFile in objFolder.Files
    For Each strExt in Split(Ucase(strExtensionsToDelete),",")
      If Right(Ucase(objFile.Path), Len(strExt)+1) = "." & strExt Then
        wscript.echo "Deleting:" & objFile.Path
        If Not testMode = True Then
          objFile.Delete
        End If
        'Exit For
      End If
    Next
  Next 
  For Each objSubFolder in objFolder.SubFolders
    RecursiveDeleteByExtension objSubFolder.Path, strExtensionsToDelete
  Next
End Sub

Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
RecursiveDeleteByExtension "d:\downloads", strExtensionsToDelete
wscript.echo "finished!"

Recursively Delete Old Files and Empty Folders

With a slight twist: The recursion to delete empty folders ignores folders with a name that begins with a tilde "~". You can modify the character or pattern to suit your demented whims.

Const maxAge = 30
Const testMode = True

Sub RecursiveDeleteByAge(ByVal strDirectory, maxAge)
 Dim objFolder, objSubFolder, objFile
 Set objFolder = objFSO.GetFolder(strDirectory)
 For Each objFile in objFolder.Files
  dlm = objFile.DateLastModified
  If DateDiff("d", dlm, Now) > maxAge Then
   wscript.echo "Deleting:" & objFile.Path
   If Not testMode = True Then
    objFile.Delete
   End If
   Exit For
  End If
 Next 
 For Each objSubFolder in objFolder.SubFolders
  RecursiveDeleteByAge objSubFolder.Path, maxAge
 Next
End Sub


Sub RecursiveDeleteEmptyFolders(ByVal strDirectory)
 Dim objFolder, objSubFolder
 Set objFolder = objFSO.GetFolder(strDirectory)
 
 If objFolder.Files.Count = 0 Then
  If objFolder.SubFolders.Count = 0 Then
   ' no sub-folders beneath this folder...
   If Left(objFolder.Name,1) <> "~" Then
    wscript.echo "deleting " & objFolder.Path
    If Not testMode = True Then
     objFolder.Delete
    End If
   End If
  Else
   For Each objSubFolder in objFolder.SubFolders
    RecursiveDeleteEmptyFolders objSubFolder.Path
   Next
  End If
 Else
  wscript.echo "folder is not empty"
  For Each objSubFolder in objFolder.SubFolders
   RecursiveDeleteEmptyFolders objSubFolder.Path
  Next
 End If
 
End Sub

Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")

RecursiveDeleteByAge "d:\downloads", maxAge
RecursiveDeleteEmptyFolders "d:\downloads"

wscript.echo "finished!"

Wednesday, September 8, 2010

Stupid-Simple, Yet Useful VBScript Functions

Ok, technically some of these are not functions, they're subs (or subroutines), but who cares.  I don't know who invented them, but I've been using these for years and years.  I hope they're helpful to you as well…

Sub Echo(category, caption)
    wscript.echo Now & vbTab category & vbTab & caption
End Sub

Examples…

Echo "info", "searching for wmi repository scope on remote computer…"

Echo "fail", "unable to connect to remote computer"

Function ScriptPath()
    ScriptPath = Replace(wscript.ScriptFullName, "\" & wscript.ScriptName, "")
End Function

Function IsWeekend(strDate)
    If Weekday(strDate)=1 Or Weekday(strDate)=2 Then
        IsWeekend = True
    End If
End Function

Function LeapYear(yr)
    Dim d1, d2
    d1 = FormatDateTime("1/1/" & yr)
    d2 = DateAdd("yyyy", 1, d1)
    If DateDiff("d", d1, d2) = 366 Then
        LeapYear = True
    End If
End Function

For i = 2004 to 2012
    If LeapYear(i) Then
        wscript.echo i & vbTab & "is a leap year"
    Else
        wscript.echo i & vbTab & "is not a leap year"
    End If
Next

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.

Thursday, September 24, 2009

VBScript - Get Previous / Next Month Names

Function NextMonthName(dateval)
    Dim tmp : tmp = DateAdd("m", 1, dateval)
    NextMonthName = MonthName(Month(tmp))
End Function


Function PrevMonthName(dateval)
    Dim tmp : tmp = DateAdd("m", -1, dateval)
    PrevMonthName = MonthName(Month(tmp))
End Function

VBScript - Checking for a Valid Date

Function DateValid(dv)
    Dim retval : retval = ""
    On Error Resume Next
    retval = FormatDateTime(dv, vbShortDate)
    If err.Number = 0 Then
        DateValid = True
    End If
End Function

Sunday, July 12, 2009

VBScript / ASP Function to Convert Dates to/from MySQL


' MySqlDate(Now, 1) --> "2008-02-20"
' MySqlDate(Now, 2) --> "2/20/2008"

Function MySqlDate( d, dir )
If Not isDate( d ) Then d = Date()
Dim strNewDate
Select Case dir
Case 1:
'=== store in db
strNewDate = Year( d ) & "-" & Month( d ) & "-" & Day( d )
Case 2:
'=== use with asp
strNewDate = Month( d )& "/" & Day( d ) & "/" & Year( d )
strNewDate = cDate( strNewDate )
End Select
mysqlDate = strNewDate
End Function

PHP: Determine Zodiac Sign from Birth Date


function ZodiacSign($date){
list($year,$month,$day)=explode("-",$date);
if (($month==1 && $day>20)||($month==2 && $day<20)) {
return "Aquarius";
} else if (($month==2 && $day>18 )||($month==3 && $day<21)) {
return "Pisces";
} else if (($month==3 && $day>20)||($month==4 && $day<21)) {
return "Aries";
} else if (($month==4 && $day>20)||($month==5 && $day<22)) {
return "Taurus";
} else if (($month==5 && $day>21)||($month==6 && $day<22)) {
return "Gemini";
} else if (($month==6 && $day>21)||($month==7 && $day<24)) {
return "Cancer";
} else if (($month==7 && $day>23)||($month==8 && $day<24)) {
return "Leo";
} else if (($month==8 && $day>23)||($month==9 && $day<24)) {
return "Virgo";
} else if (($month==9 && $day>23)||($month==10 && $day<24)) {
return "Libra";
} else if (($month==10 && $day>23)||($month==11 && $day<23)) {
return "Scorpio";
} else if (($month==11 && $day>22)||($month==12 && $day<23)) {
return "Sagittarius";
} else if (($month==12 && $day>22)||($month==1 && $day<21)) {
return "Capricorn";
}
}

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"

VBScript / ASP Determine Next Pay Date


Function NextPayDate()
Dim wd, base : base = CDate("6/12/2009")
Dim today : today = Now
If IsPayDate(today) Then
NextPayDate = today
Else
wd = WeekDay(today)
Select Case wd
Case 6:
' if today is a friday
If IsPayDate(DateAdd("d", 14, today)) Then
NextPayDate = DateAdd("d", 14, today)
End If
Case 7:
' if today is a saturday
If IsPayDate(DateAdd("d", 6, today)) Then
NextPayDate = DateAdd("d", 6, today)
Else
NextPayDate = DateAdd("d", 13, today)
End If
Case Else:
If IsPayDate(DateAdd("d", 6-wd, today)) Then
NextPayDate = DateAdd("d", 6-wd, today)
Else
NextPayDate = DateAdd("d", 13-wd, today)
End If
End Select
End If
End Function

VBScript / ASP Is-PayDate (Crude Version)

Returns True if [dateval] is a multiple of 14 days (two weeks) from a known base pay date in the past (I picked June 12, 2009).


Function IsPayDate(dateval)
Dim days
Dim base : base = CDate("6/12/2009")
If WeekDay(dateval) = 6 Then
days = DateDiff("d", base, dateval)
If (days Mod 14) = 0 Then
IsPayDate = True
End If
End If
End Function

Example...


For each d in Split("7/2/2009,7/3/2009,7/10/2009,7/24/2009", ",")
If IsPayDate(d) Then
wscript.echo d & " is a pay date"
Else
wscript.echo d & " is not a pay date"
End If
Next

Friday, July 3, 2009

VBScript / ASP Function Days-In-Month


Function DaysInMonth(dateval)
Dim nxt
Dim tmp : tmp = DateAdd("d", -(Day(dateval)-1), dateval) ' get first day of month
nxt = DateAdd("m", 1, tmp) ' get first day of next month
DaysInMonth = Day(DateAdd("d", -1, nxt))
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