A couple questions come to mind - Do you have to take holidays into account? What country(s)/state(s)/local juristions are under consideration? Is this for any year or just the upcoming year?
You'll either need to set up a Holiday table and/or check whether a given date is a holiday. Most national holidays are pretty easy to figure out, but if you have to deal with state holidays it gets more compilcated. (Although if you are only concerned about the beginning of the month, then the list is a bit smaller.)
The code I'd use to check genericaly, is to use DOW() starting on the 2nd of the month, and make sure it isn't Saturday or Sunday (1 or 7), then check the calendar to possibly eliminate it due to a holiday. Loop until you have your two candidates for the 2nd and 3rd business day.
I've developed the following code to determine US holidays. Every recurring holiday can be determined by a formula, so this can be easily adapted to any country once you identify the 'rules'.
Steve
** SELECTED PUBLIC VARIABLES
*-- Set to .T. to observe Christmas on Friday/Monday for weekend days.
glweekendchristmas = .F.
*-- Set to .T. to observe Independence Day on Friday/Monday for weekend days.
glweekendjuly4 = .F.
*-- Set to .T. to observe New Years Day on Monday for weekend days.
glweekendnewyear = .F.
*-- Holds the text string for a holiday. Will be used in place of the CDOW/MDY when populated
gcHoliday = ""
** Pass 'mHolidayTest' the date and question and check 'gcHoliday' to determine if a holiday is appropriate
LOCAL lcStr
lcStr = .null.
DO CASE
* Friday Observances of Saturday Holidays
CASE glweekendJuly4 AND MONTH(tdDate) = 7 AND DAY(tdDate) = 3 AND DOW(tdDate) = DOW_FRIDAY
*-- July 4th is a Saturday - Observed on Friday
lcStr = "Independence DAY (OBSERVED)"
CASE glweekendChristmas AND MONTH(tdDate) = 12 AND DAY(tdDate) = 24 AND DOW(tdDate) = DOW_FRIDAY
*-- Christmas is a Saturday - Observed on Friday
lcStr = "Christmas Day (OBSERVED)"
*-- New Years Day on Saturday will NEVER be observed on Friday, Dec. 31
* Monday Observances of Sunday Holidays
CASE glweekendJuly4 AND MONTH(tdDate) = 7 AND DAY(tdDate) = 5 AND DOW(tdDate) = DOW_MONDAY
*-- July 4th is a Sunday - Observed on Monday
lcStr = "Independence DAY (OBSERVED)"
CASE glweekendChristmas AND MONTH(tdDate) = 12 AND DAY(tdDate) = 26 AND DOW(tdDate) = DOW_MONDAY
*-- Christmas is a Sunday - Observed on Monday
lcStr = "Christmas Day (OBSERVED)"
CASE glweekendNewYear AND MONTH(tdDate) = 1 AND DAY(tdDate) = 2 AND DOW(tdDate) = DOW_MONDAY
*-- New Years is a Sunday - Observed on Monday
lcStr = "New Years Day (OBSERVED)"
* Fixed Day Holiday Observances
** NOTE: US Federal Reserve (and therefore banks) observe Columbus Day (2nd Mon. in October)
** NOTE: US Federal Reserve (and therefore banks) observe Veterans Day (Nov.11)
CASE MONTH(tdDate) = 1 AND DOW(tdDate) = DOW_MONDAY AND BETWEEN(DAY(tdDate),15,21)
** 3rd Monday of January
lcStr = "Martin Luther King, Jr. Day"
CASE MONTH(tdDate) = 2 AND DOW(tdDate) = DOW_MONDAY AND BETWEEN(DAY(tdDate),15,21)
** 3rd Monday of February
lcStr = "President's Day"
CASE MONTH(tdDate) = 11 AND DOW(tdDate) = DOW_THURSDAY AND BETWEEN(DAY(tdDate),22,28)
** 4th Thursday of November
lcStr = "Thanksgiving"
CASE mIsEaster(tdDate+2) && Good Friday
** 2 Days before Easter
lcStr = "Good Friday"
CASE MONTH(tdDate) = 9 AND DOW(tdDate) = DOW_MONDAY AND DAY(tdDate) <= 7 && Labor Day
** 1st Monday in September
lcStr = "Labor Day"
CASE MONTH(tdDate) = 5 AND DOW(tdDate) = DOW_MONDAY AND DAY(tdDate) >= 25 && Memorial Day
** Last Monday in May
lcStr = "Memorial Day"
* Fixed Date Holiday Observances - Their status may be overridden by individual weekend rule properties.
CASE MONTH(tdDate) = 7 AND DAY(tdDate) = 4 && Independence Day
** Always July 4th - Observance may float depending upon weekend rule.
lcStr = "Independence Day"
CASE MONTH(tdDate) = 1 AND DAY(tdDate) = 1 && New Years Day
** Always January 1st - Observance may float depending upon weekend rule.
lcStr = "New Years Day"
CASE MONTH(tdDate) = 12 AND DAY(tdDate) = 25 && Christmas Day
** Alwasy December 25th - Observance may float depending upon weekend rule.
lcStr = "Christmas Day"
ENDCASE
IF LEN(ALLTRIM(lcStr)) > 2
gcHoliday = lcStr
RETURN .T.
ELSE
gcHoliday = ""
RETURN .F.
ENDIF
*******************
PROCEDURE mIsEaster
*******************
*-- Returns .T. if the passed date is Easter Sunday.
LPARAMETERS tdDate
LOCAL lnYear, valB, valD, valE, valQ, lcEaster
lnYear = YEAR(tdDate)
valB = 225 - 11 * (MOD(lnYear,19))
valD = MOD((valB-21),30) + 21
IF valD > 48
valD = valD - 1
ENDIF
valE = MOD(lnYear + (lnYear/4) + valD + 1,7)
valQ = valD + 7 - valE
IF valQ < 32
lcEaster = "03/" + ALLTRIM(STR(valQ)) + "/" + ALLTRIM(STR(lnYear))
ELSE
lcEaster = "04/" + ALLTRIM(STR(valQ-31)) + "/" + ALLTRIM(STR(lnYear))
ENDIF
RETURN CTOD(lcEaster) = tdDate
Nice bit of code SGLong, I'll take a more thorough look at it when time permits, but looks promising and I like the inclusion of Monday and Friday observances. Star for the effort and for sharing.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.