erik7426 Posted June 22, 2011 Share Posted June 22, 2011 I need to write a script to perform certain tasks on a server on certain days. There are tasks to be done every Friday. (No Problem) There are tasks to be done on the 1st and 15th of the month. (No Problem) I have no problem checking today's date against those conditions. Where I'm running into problems is checking today's date against specific days of the month. Example: How can I tell if today is the last Tuesday of the month? Last Thursday of the month? etc... I found this script on the forum, but either I don't fully understand how to use it or it doesn't meet my needs. expandcollapse popup#Region Func _OkToRun #cs ---------------------------------------------------------------------------- AutoIt Version : 3.2.10.0 Author : Christophe Savard Script Function : Checks if today's the first Monday following the first Friday of the month" Parameters : $RundDay (Mandatory) - Weekday number (integer) when the script must run (1 = Sunday to 7 = Saturday) $DayToTest (Optional) - Day number (interger) of the day to test Possible values : Null ==> $RunDay value is considered as the target (same as schedule a basic weekly task) An interger ==> Value must be higher than the $RunDay value (otherwise it's a basic weekly run) $Occurence (Optional) - Occurrence of the $DayToTest in the month (Default = 1) Possible values : Null ==> default value is used (the first Occurrence = 1) if $DayToTest value is not empty -1 ==> the last Occurrence of the $DayToTest value if existing ==> All Occurrences of $RunDay value if $DayToTest value is blank (it's a weekly run in fact) -2 ==> the last occurence of the $DayToTest value An integer ==> the value will be used if it's in the range of date between day 1 and the $RunDay value. If the value is out of range sript stops and return an error message e.g : You try to test the 5th Friday of the month and the current month only contains 4 Fridays. $Occurence (Optional) - Full path to a log file Sample syntax : If you want the script to run the Monday following the first Friday of the month the syntax will be : $OK = _OkToRun (2,6,1) or _OkToRun (2,6) If you want the script to run each Monday then the syntax will be : OK = _OkToRun (2) Return value : On success - 1 On failure - 0 (and place a formated error message in a writelogfile) Requirement(s) : #include <Date.au3> #ce ---------------------------------------------------------------------------- Func _OkToRun ($RunDay,$DayToTest,$Occurrence = 1, $LogFullPath="") If $LogFullPath then _FileWriteLog($LogFullPath,"===== START PROCESS " & _StringRepeat('=',80)) Local $Retval = "", $Y, $M, $D #region Control of parameters validity and value If (Not IsInt ($RunDay) And $RunDay <> "") Or (IsInt ($RunDay) And ($RunDay > 7 Or $RunDay <= 0)) then $Retval = $Retval & "Parameter 1 cannot be " & '"' & $RunDay & '"' & ". It must be an Integer between 1 & 7." & @LF If $Runday= "" then $Retval = $Retval & "Parameter 1 is mandatory (a running day must be provided)." & @LF If (Not IsInt ($DayToTest) And $DayToTest <> "") Or (IsInt ($DayToTest) And ($DayToTest > 7 Or $DayToTest <= 0) ) then $Retval = $Retval & "Parameter 2 cannot be " & '"' & $DayToTest & '"' & ". Possible values are : an Integer between 1 & 7 / Null value" & @LF If $DayToTest = $RunDay and $DayToTest <> "" then $Retval = $Retval & "Parameter 2 cannot be equal to parameter 1. the target day to test cannot be the running day !" & @LF If (Not IsInt ($Occurrence) And $Occurrence <> "") Or (IsInt ($Occurrence) And ($Occurrence = 0 Or $Occurrence > 4)) then $Retval = $Retval & "Parameter 3 cannot be " & '"' & $Occurrence & '"' & ". Possible values are : a number between 1 and 4 / [-1] for all Occurrences (weekly run) / [-2] for the last Occurrence / Null value" & @LF If $Occurrence = "" And $DayToTest <> "" then $Occurrence = 1; Set the default value for Occurence only if $DayToTest value is not empty... If $Occurrence = "" And $DayToTest = "" then $Occurrence = -1; otherwise set $Occurrence value to "all" (equivalent to a weekly run) If $Occurrence <> "" And $DayToTest = "" then $DayToTest = $RunDay; Weekly run but with an Occurrence condition (ex : 1st monday of the month) If $Retval then; Prepare retval for logfile update $SplitedRetval = StringSplit($Retval,@LF) For $i = 1 To $SplitedRetval[0] If $LogFullPath then _FileWriteLog($LogFullPath,$SplitedRetval[$i]) If $i = $SplitedRetval[0]-1 then ExitLoop Next If FileExists($LogFullPath) then _FileWriteLog($LogFullPath,"===== PROCESS ABORTED " &_StringRepeat('=',80)) Return 0; Exit function if $Retval is not empty EndIf If @WDAY <> $RunDay then; Exit if today is not the Day number required by $Runday parameter If $LogFullPath then _FileWriteLog($LogFullPath, "Requested Run day is " & _DateDayOfWeek($RunDay,0) & " ==> Today is " & _DateDayOfWeek(@WDAY,0) & " !") If $LogFullPath then _FileWriteLog($LogFullPath,"===== PROCESS ABORTED " &_StringRepeat('=',80)) Return 0 ElseIf @WDAY = $RunDay then; Today's is the day... If $Occurrence = -1 then If $LogFullPath then _FileWriteLog($LogFullPath,'Process run is granted !') If $LogFullPath then _FileWriteLog($LogFullPath,"===== END PROCESS " &_StringRepeat('=',80)) Return 1; and $Occurrence = -1 this means it's a weekly run in fact EndIf EndIf #endregion Control of parameters validity and value #region Offset Calculation If $DayToTest <> $Runday then If $DayToTest > $Runday then $OffSet = $Runday + (7 - $DayToTest); Calculates the Offeset between $Runday and $DayToTest Else $OffSet = $Runday - $DayToTest EndIf EndIf #endregion Offset calculation #region $Occurrence consistancy test $ActualMthDayNbr = @MDAY; Gets the actual day number of the month Local $WeekDays[1] = [0] , $DayNum For $i=1 to $ActualMthDayNbr; loop to identify all the $Daytotest values in the month until today and gets the related dates $DayNum=_DateToDayOfWeek(@YEAR, @MON, $i) If $DayNum = $DayToTest then $WeekDays[0] += 1; adds 1 to the array counter ReDim $WeekDays[$WeekDays[0]+1]; Increase the boundary If StringLen($i) = 1 then $WeekDays[$WeekDays[0]]= @YEAR & @MON & "0" & $i; Load the array element with the formated date. Else $WeekDays[$WeekDays[0]]= @YEAR & @MON & $i; Load the array element with the formated date. EndIf EndIf Next If $Occurrence > $WeekDays[0] then If $LogFullPath then _FileWriteLog($LogFullPath,"Requested Occurrence is " & $Occurrence & " (parameter 3) " & "and the total available occurrences available up to now is " & $WeekDays[0] & "... ==> It's to early." &_StringRepeat('=',80)) If $LogFullPath then _FileWriteLog($LogFullPath,"===== PROCESS ABORTED " &_StringRepeat('=',80)) Return 0 EndIf #endregion $Occurrence consistancy test If @Compiled=0 then _ArrayDisplay($WeekDays) #region Date checks If $Occurrence = -2 then $DateOfDaytoTest=$WeekDays[$WeekDays[0]]; Takes the last value in the array and therefore the target date just before the rundate. Else $DateOfDaytoTest=$WeekDays[$Occurrence]; Takes the value following $Occurrence parameter EndIf If @Compiled = 0 then MsgBox(0,"$DateOfDaytoTest",$DateOfDaytoTest) $JulianRunday = _DateToDayValue (@YEAR , @MON , @MDAY); Translate the $RundDay date into a julian date value _DayValueToDate ($JulianRunday - $Offset, $Y, $M, $D); Substracts the $Offset value to the $JulianRundDay value If $Y & $M & $D = $DateOfDaytoTest then; compare the previous result with the result obtained just above If $LogFullPath then _FileWriteLog($LogFullPath,'Process run is granted !') If $LogFullPath then _FileWriteLog($LogFullPath,"===== END PROCESS " &_StringRepeat('=',80)) Return 1; Dates are the same => Run can be done Else If $LogFullPath then _FileWriteLog($LogFullPath,"The target date is " & $DateOfDaytoTest & " (Occurrence N° " & $Occurrence & " of the month)" & " and today's is to late !") If $LogFullPath then _FileWriteLog($LogFullPath,"===== PROCESS ABORTED " &_StringRepeat('=',80)) Return 0 EndIf #endregion Date checks EndFunc #endregion Func _OkToRun Any help would be greatly appreciated. Link to comment Share on other sites More sharing options...
JohnOne Posted June 22, 2011 Share Posted June 22, 2011 Heres my go #include <Date.au3> $iDays = _DateDaysInMonth(@YEAR, @MON) For $i = $iDays - 7 To $iDays $iWeekday = _DateToDayOfWeek(@YEAR, @MON, $i) If $iWeekday = 3 Then $LastTuesdayofmonth = $i ExitLoop EndIf Next MsgBox(4096, "", "Last tuesday of month is: " & $LastTuesdayofmonth) AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
enaiman Posted June 23, 2011 Share Posted June 23, 2011 Well, you can use JohnOne's solution if you are after getting ONE (last Tuesday, Friday ...) or, you can use this: #include<date.au3> #include<array.au3> $DaysInMonth = _DateDaysInMonth(@YEAR, @MON) ;how many days the current month has $LastDayInMonth = _DateToDayOfWeek(@YEAR, @MON, $DaysInMonth) ;last day in the month (date format) Dim $LastNamedDays[7][2] ;array of [dates][last Weekday in month] For $i = 0 To 6 $LastNamedDays[$i][0] = @YEAR&"/"&@MON&"/"&_DateDaysInMonth(@YEAR, @MON)-$i If $LastDayInMonth - $i > 0 Then $LastNamedDays[$i][1] = "Last "&_DateDayOfWeek(Mod($LastDayInMonth-$i,7)) Else $LastNamedDays[$i][1] = "Last "&_DateDayOfWeek(Mod($LastDayInMonth-$i,7)+7) EndIf Next _ArrayDisplay($LastNamedDays) To get an array with Last "Weekdays" in current month. The output is like this: 2011/06/30|Last Thursday 2011/06/29|Last Wednesday You can easily match a date to a certain weekday - well, you will need to adapt the code to suit your needs. Pretty straightforward from here. SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script wannabe "Unbeatable" Tic-Tac-Toe Paper-Scissor-Rock ... try to beat it anyway :) Link to comment Share on other sites More sharing options...
Malkey Posted June 23, 2011 Share Posted June 23, 2011 .... How can I tell if today is the last Tuesday of the month? Last Thursday of the month? etc... .... Another interpretation of your problem. #include<Date.au3> Local $aNewDate = StringSplit(_DateAdd('d', 7, _NowCalcDate()), "/", 2) ; Add 7 days to today and split into an array. Local $sToday = _DateDayOfWeek(_DateToDayOfWeek(@YEAR, @MON, @MDAY)); If $aNewDate[1] <> @MON Then ; If the month in 7 days does not equal today's month then MsgBox(4096, "", "Today is the last " & $sToday & " of this month.") Else MsgBox(4096, "", "Today is not the last " & $sToday & " of this month.") EndIf Link to comment Share on other sites More sharing options...
erik7426 Posted June 23, 2011 Author Share Posted June 23, 2011 Thanks to everyone who replied. In the end I used Malkey's response because it needed the least amount of adjustment to fit into my existing script. From his response I ended up with this function... Func CheckDay() ;Function Returns Day of the Week. Range is 1 to 7 where 1=Sunday. Local $aNewDate = StringSplit(_DateAdd('d', 7, _NowCalcDate()), "/", 2) ; Add 7 days to today and split into an array. Local $sToday = _DateToDayOfWeek(@YEAR, @MON, @MDAY) If $aNewDate[1] <> @MON Then ; If the month in 7 days does not equal today's month then Return $sToday Else Return 0 EndIf EndFunc ;==>CheckDay Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now