I'm using a single WSH script controlled by Microsoft Task Scheduler that calls a series of daily run batch files sequentially. However, some of these batch files only need to run on the first working day of each month. I don't want to create additional Task Scheduled events for these monthly tasks as I want to control and maintain everything from this single WSH script.

I'm using some functions within the script to work out if it's the the first working day of the month. If this is true, than those monthly batch files can be executed.

Below is some WSH code I've been working on and its been adapted from some Visual Basic code sourced at this site. http://www.tek-tips.com/viewthread.cfm?qid=147546&page=1941

Using the same concepts shown at that site, I have converted to it to WSH as best as could with some slight modifications and now have two basic functions called IsWorkingDay and IsFirstWorkingDay. The code has a bug and I just can't seem to get it right. It's works okay for April 2011 but not for May 2011.

I'd appeaciate any help in fixing this or making any conceptual improvements.

' ******************************************************************
' Determine if the current day is the first working day of the month.
' Working day is defined as any day from Monday to Friday.

iDayOfWeek = Weekday(Now) 
wscript.echo "Day of Week as Numerical constant: " & iDayOfWeek

' Test if current day in the week is a working day 
if (IsWorkingDay = True) then
  Wscript.Echo "True - Today is a Working Day."
else
  Wscript.Echo "False - Today is not a working day, it's the weekend."
end if

' ********************************************************************
' Function: IsWorkingDay
'     Task: Determine if day of week is a working day (e.g. Mon to Fri)
'    Input:  
'   Output: True/False  

Function IsWorkingDay

  iDow = Weekday(Now)
  if (iDow >= 2) and (iDow <= 6) then
    IsWorkingDay = True
  else 
    IsWorkingDay = False 
  end if 
End Function




' Today is the first working day this month if  
' the previous working day was not in the month.

if (IsFirstWorkingDay = True) then
  Wscript.Echo "True - It's the first working day of the month"
else
  Wscript.Echo "False - It's not the first working day of the month"
end if


' ********************************************************************
' Function: IsFirstWorkingDay
'     Task: Determine if it's the first working day of the month
'    Input: 
'   Output: True/False 

Function IsFirstWorkingDay
  
  IsFirstWorkingDay = False
  If (IsWorkingDay = True) Then       
    IsFirstWorkingDay = True  ' Assume it is the first working day of the month 
	                      ' but test the assumption.
    Do
      i = i + 1
      If Month(Now - i) <> Month(now) Then
         Exit do ' Eureka
      End If
      
      If IsWorkingDay Then ' was right to begin with
         IsFirstWorkingDay = False
         Exit do
      End If

    Loop

  End If 

End Function

Regards

Tony

Okay, I've had a another go at it and I think I solved my problem this time.
Revised code below.

' ********************************************************************
' Script Language: 
' Windows Script Host
'
' Task:
' Determine if the current day is the first working day of the month.
' Working day is defined any day from Monday to Friday.

TheDayOfWeek = Weekday(Now) 
wscript.echo "Full Date: " & now
wscript.echo "Short Date: " & date
wscript.echo "Day of Week as Numerical Constant: " & TheDayOfWeek


' Test if day in the week is a working day... 
If (IsWorkingDay(Date) = True) Then
  Wscript.Echo "True - Today is a Working Day."
Else
  Wscript.Echo "False - Today is not a working day, it's the weekend."
End If

' *********************************************************************
' Function: IsWorkingDay()
'     Task: Determine if day-of-week is a working day (e.g. Mon to Fri)
'    Input: Short Date (e.g. 29/04/2011) 
'   Output: True/False  

Function IsWorkingDay(today)
  iDayOfWeek = Weekday(today)
  If (iDayOfWeek >= 2) and (iDayOfWeek <= 6) Then
    IsWorkingDay = True
  Else 
    IsWorkingDay = False 
  End If 
End Function


' Today is the first working day this month if  
' the previous working day was not in the month.

If (IsFirstWorkingDay(Date) = True) Then
  Wscript.Echo "True - It's the first working day of the month."
Else
  Wscript.Echo "False - It's not the first working day of the month."
End If


' ********************************************************************
' Function: IsFirstWorkingDay()
'     Task: Determine if it's the first working day of the month
'    Input: Short Date (e.g. 29/04/2011)
'   Output: True/False  

Function IsFirstWorkingDay(today)
    
  ' Start By assuming that Today is not a working day.
  
  IsFirstWorkingDay = False
  If (IsWorkingDay(today) = True) Then    ' Assumption may be wrong    
    IsFirstWorkingDay = True              ' Test it
    i = today                          
	                            
    Do
      i = i - 1  
      If Month(i) <> Month(today) Then
         Exit do ' Eureka
      End If
      
      If (IsWorkingDay(i) = True) Then ' was right to begin with
         IsFirstWorkingDay = False
         Exit do
      End If
    Loop
  
  End If 

End Function

Regards,

Tony

Why not just start from the first of the month? If we continue to ignore holidays (or handle them as special cases) there are three possible cases: Saturday, Sunday, or other. If the first of the month is Saturday, 1st working day is Monday (the third). If Sunday, then 1st working day is is Monday (the second). Otherwise, the first working day is the first of the month.

Having the first working day of the month in hand, isFirstWorkingDay is obviously trivial.

Comments
Clear thinking!

Thanks Jon...your suggested logic is much simpler! Here is my code with the the logic and it seems do the trick (much less convoluted than the first approach).

' Determine if today's date is the first working day of the month.
' Just in this case, igore holdays.

' Get the Current Year...
iYear = Year(Date)

' Get the current month...
iMonth = Month(date)

' Use zero parameter on dataserial to get the last date of the previous month 
' then forward it by one day by adding 1 to get the short date for the 1st of 
' the current month.
FirstDayOfMonth = (dateserial(iYear,iMonth,0))+1
wscript.echo "First day of the current month is: " & FirstDayOfMonth

'Saturday check...
if WeekDay(FirstDayOfMonth, 1) = 7 Then
  FirstDayOfMonth = FirstDayOfMonth + 2
  wscript.echo "First Working Day of the current month is: " & FirstDayOfMonth
End if

'Sunday check...
if WeekDay(FirstDayOfMonth, 1) = 1 Then
  FirstDayOfMonth = FirstDayOfMonth + 1
  wscript.echo "First Working Day of the current month is: " & FirstDayOfMonth
End if

' Now determine if today is the first working day of the month
If Date = FirstDayOfMonth Then
 wscript.echo "Today is the first working day of the month."
Else
 wscript.echo "Today is not the first working day of the month." 
End If

Regards,

Tony

Good thinking Jon!

Still I do not get why you must be so complicated, those extra variables do not help anything for my opinion. I can write this in Python as I do not like to learn quirks of your BASIC.

Here is my Python code, even this is obviously needless optimization, still do not consider the Holidays like New Year (also posted to Python Snippets: http://www.daniweb.com/software-development/python/code/363346/1554008#post1554008):

from datetime import datetime

def first_workday(theday):
    ''' Determine first workday based on day of month and workday (0 == Monday) '''
    return ((theday.day == 3 and theday.weekday() == 0) or
            (theday.day == 2 and theday.weekday() == 0) or
            (theday.day == 1 and theday.weekday() < 5))


for test in (datetime.today(), datetime(2011, 5, 2), datetime(2010, 5, 2), datetime(2011, 5, 1),
             datetime(2011, 4, 1), datetime(2011, 3, 1), datetime(2011, 1, 1), datetime(2012, 9, 1),
            datetime(2012, 9, 3), datetime(2010, 1, 1)): # wrong as New Year is Holiday
        print 'The day is' + ('' if first_workday(test) else ' not'), 'first workday:',  test.strftime('%Y/%m/%d, %A')
    
'''Output:
The day is not first workday: 2011/05/07, Saturday
The day is first workday: 2011/05/02, Monday
The day is not first workday: 2010/05/02, Sunday
The day is not first workday: 2011/05/01, Sunday
The day is first workday: 2011/04/01, Friday
The day is first workday: 2011/03/01, Tuesday
The day is not first workday: 2011/01/01, Saturday
The day is not first workday: 2012/09/01, Saturday
The day is first workday: 2012/09/03, Monday
The day is first workday: 2010/01/01, Friday
'''

Edited 5 Years Ago by pyTony: n/a

Since we are talking Python, you can also use Python module calendar ...

# print the first workday (Mon - Fri) of each month in a given year
# Monday is first day of week by default
# tested with Python27 and Python32  by  vegaseat

import calendar

# change these values to your needs ...
year = 2011

# be nice
days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']

print("All first workdays of each month in %d:" % year)
# go 3 days into each month in case it starts with Saturday, Sunday
for ix, month in enumerate(range(1, 13)):
    for day in range(1, 4):
        weekday = calendar.weekday(year, month, day)
        if weekday < calendar.SATURDAY:
            # format the result
            sf = "%2d) %s  %02d/%02d/%d"
            print(sf % (ix+1, days[weekday], month, day, year))
            break

"""my output -->
All first workdays of each month in 2011:
 1) Mo  01/03/2011
 2) Tu  02/01/2011
 3) Tu  03/01/2011
 4) Fr  04/01/2011
 5) Mo  05/02/2011
 6) We  06/01/2011
 7) Fr  07/01/2011
 8) Mo  08/01/2011
 9) Th  09/01/2011
10) Mo  10/03/2011
11) Tu  11/01/2011
12) Th  12/01/2011
"""

# for extra checking only
#print(calendar.prcal(2011))

Edited 5 Years Ago by vegaseat: n/a

Nice module, and by chance checking OP's history of posts he has posted to Python forum earlier.

Point of the function is to determine if the given day is first workday of month and if is do some work. To simplify my code it is possible to use date instead of datetime and it is possible to drop one boolean by joining the weekday cases.

from datetime import date

def isfirst_workday(theday):
    ''' Determine first workday based on day of month and weekday (0 == Monday) '''
    return ((theday.day in (2,3) and theday.weekday() == 0) or
            (theday.day == 1 and theday.weekday() < 5))


for test in (date.today(), date(2011, 5, 2), date(2010, 5, 2), date(2011, 5, 1),
             date(2011, 4, 1), date(2011, 3, 1), date(2011, 1, 1), date(2012, 9, 1),
            date(2012, 9, 3), date(2010, 1, 1)): # wrong as New Year is Holiday
        print 'The day is' + ('' if isfirst_workday(test) else ' not'), 'first workday:',  test.strftime('%Y/%m/%d, %A')
    
'''Output:
The day is not first workday: 2011/05/07, Saturday
The day is first workday: 2011/05/02, Monday
The day is not first workday: 2010/05/02, Sunday
The day is not first workday: 2011/05/01, Sunday
The day is first workday: 2011/04/01, Friday
The day is first workday: 2011/03/01, Tuesday
The day is not first workday: 2011/01/01, Saturday
The day is not first workday: 2012/09/01, Saturday
The day is first workday: 2012/09/03, Monday
The day is first workday: 2010/01/01, Friday
'''
This question has already been answered. Start a new discussion instead.