home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
progmisc
/
dblib201.zip
/
DATES.PRG
< prev
next >
Wrap
Text File
|
1993-04-02
|
66KB
|
1,582 lines
*-------------------------------------------------------------------------------
*-- Program...: DATES.PRG
*-- Programmer: Ken Mayer (CIS: 71333,1033)
*-- Date......: 02/24/1993
*-- Notes.....: These are the date functions/procedures I felt were not as
*-- commonly used as those left behind in PROC.PRG. See README.TXT
*-- for details on the use of this library file.
*-------------------------------------------------------------------------------
FUNCTION DateText3
*-------------------------------------------------------------------------------
*-- Programmer..: Miriam Liskin
*-- Date........: 03/02/1992
*-- Notes.......: Display date in format Month, year
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 05/21/1991 - original function.
*-- 03/02/1992 - This one's Douglas P. Saine's (XRED) invention.
*-- In his words: "I just removed the middle part looking for
*-- the day. For the things I do, I only need the month and
*-- year. (I work for a defense contracter, accuracy of dates
*-- has never been of great concern. <G>)"
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: DateText3(<dDate>)
*-- Example.....: ? DateText3(date())
*-- Returns.....: July, 1991
*-- Parameters..: dDate = date to be converted
*-------------------------------------------------------------------------------
parameters dDate
RETURN cmonth(dDate)+", "+str(year(dDate),4)
*-- EoF: DateText3()
FUNCTION Age2
*-------------------------------------------------------------------------------
*-- Programmer..: Martin Leon (HMAN)
*-- Date........: 04/22/1992
*-- Notes.......: Returns number of full years between two dates, which is
*-- age of a person born on the first date as of the second.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 10/23/1991 - original function.
*-- 04/22/1992 -- Description modified, parameters changed by
*-- Jay Parsons (CIS: 70160,340).
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: Age2(<d1>,<d2>)
*-- Example.....: ? "Joe was "+ltrim(str(age2(dBDay,{10/16/85})))+;
*-- " on the day of ..."
*-- Returns.....: Numeric value in years
*-- Parameters..: d1 = first date, such as date of birth
*-- d2 = second date, when age is wanted
*-------------------------------------------------------------------------------
parameters d1, d2
private nYears
nYears = year(d2) - year(d1)
do case
case month(d1) > month(d2)
nYears = nYears - 1
case month(d1) = month(d2)
if day(d1) > day(d2)
nYears = nYears - 1
endif
endcase
RETURN nYears
*-- EoF: Age2()
FUNCTION IsLeap
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 01/13/1992
*-- Notes.......: Is the year given a Leap Year? Year given must be after 1500
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/08/1991 - original function.
*-- 01/13/1992 -- updated to handle two digit OR four digit year.
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: IsLeap(<nYear>)
*-- Example.....: IsLeap(91)
*-- Returns.....: Logical (.t./.f.)
*-- Parameters..: nYear = Numeric form of year -- last two digits (i.e., 91),
*-- or all four digits (i.e., 1991)
*-------------------------------------------------------------------------------
parameter nYear
private lReturn
*-- deal with two digit year ...
if nYear < 100
nYear = nYear + 100 * int(year(date())/100)
endif
lReturn = mod(iif(mod(nYear,100)=0,nYear/100,nYear),4)=0
RETURN lReturn
*-- EoF: IsLeap()
FUNCTION Annivrsry
*-------------------------------------------------------------------------------
*-- Programmer..: David Love (CIS: 70153,2433) and Jay Parsons (CIS: 70160,340)
*-- Date........: 11/10/1991
*-- Notes.......: Checks to see if an anniversary date falls within a range of
*-- dates (handy for mailings for organizations, checking to see
*-- if someone's birthday falls within certain dates, etc.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/10/1991 -- Original Release
*-- Calls.......: AGE2() Function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: Annivrsry(<dTest>,<dBegin>,<dEnd>)
*-- Example.....: if Annivrsry(dBDay,{03/01/91},{03/31/91})
*-- *-- do something
*-- endif
*-- Returns.....: .t. if a date (dTest) falls within the period beginning at
*-- dBegin or ending at dEnd, inclusive. .F. for any other
*-- occurance, including invalid ranges or blank dates.
*-- Parameters..: dTest = Date being tested for ...
*-- dBegin = Beginning of range
*-- dEnd = End of range
*-------------------------------------------------------------------------------
parameters dTest, dBegin, dEnd
private nYears
nYears = 0
if dBegin <= dEnd .AND. dTest <= dEnd && will be false if blank
nYears = age2(dTest,dEnd) - iif(dTest < dBegin,age2(dTest,dBegin-1),0)
endif
RETURN nYears > 0
*-- EoF: Annivrsry()
FUNCTION AddMonths
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 11/10/1991
*-- Notes.......: Finds same day as given date N months ahead.
*-- This function will return the first day of the following
*-- month if there is no date in the month otherwise returned
*-- and nMonths is positive, or the last day of the month if
*-- nMonths is negative. That is, a call with {01/31/91}
*-- (January 31, 1991) and 1 would yield March 1, there being
*-- no February 31.
*-- Do not use this function successively to find first the
*-- date one month ahead, then the date one month beyond that.
*-- Instead, to find the date two months ahead from the original
*-- date, call this function with the original date and
*-- nMonths = 2. Otherwise, in the example, you'll get April 1
*-- the second time rather than the correct March 31.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/10/1991 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: AddMonths(<dDate>,<nMonths>)
*-- Example.....: ?AddMonths({01/01/91},1)
*-- Returns.....: Date
*-- Parameters..: dDate = Date being tested for ...
*-- dMonths = Number of months "ahead"
*-------------------------------------------------------------------------------
parameters dDate, nMonths
private dNew, dTest,dReturn
dNew = dDate - day(dDate)+ 15 + 30.436875 * nMonths && middle of month
dTest = dNew - day(dNew) + day(dDate)
dReturn = iif(month(dTest) = month(dNew),dTest, ;
dTest - day(dTest) + iif(nMonths > 0, 1, 0))
RETURN dReturn
*-- EoF: AddMonths()
FUNCTION AddYears
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 11/14/1991
*-- Notes.......: Finds same day as given date N years ahead.
*-- Using this function dBASE IV will take care of converting
*-- February 29 to March 1 if moving from a leap to a non-leap
*-- year. However, neither may be used backwards (negative
*-- value of nYears) since the date a year before February 29,
*-- 1992 will be returned as March 1, 1991, not February 28, 1991.
*-- If you must move back, either check explicitly for February 29
*-- as the original date or add code as in the addmonths()
*-- function to test for the date returned being of a different
*-- month than the original and, if it is, to subtract its day().
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/10/1991 - original function.
*-- 11/14/1991 - Ken Mayer - expanded out to make it easier
*-- to read, and see what's happening.
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: AddYears(<dDate>,<nYears>)
*-- Example.....: ?AddYears({01/01/91},1)
*-- Returns.....: Date
*-- Parameters..: dDate = Date being tested for ...
*-- dYears = Number of Years "ahead"
*-------------------------------------------------------------------------------
parameters dDate, nYears
private cYear,cMonth,cDay,dReturn
cYear = str(year(dDate) + nYears)
cMonth = right(str(month(dDate) + 100),2)
cDay = right(str(day(dDate) + 100),2)
dReturn = ctod(cMonth+"/"+cDay+"/"+cYear)
RETURN dReturn
*-- EoF: AddYears()
FUNCTION DoY
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 11/14/1991
*-- Notes.......: Returns the day of the year of a date (from beginning of the
*-- year).
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/10/1991 - original function.
*-- 11/14/1991 - Ken Mayer - expanded for readability ...
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: DoY(<dDate>)
*-- Example.....: ?DoY({01/01/91})
*-- Returns.....: Numeric value of day of year
*-- Parameters..: dDate = Date being tested for ...
*-------------------------------------------------------------------------------
parameters dDate
private cYear,dStart,nReturn
cYear = right(str(year(dDate)),2)
dStart = ctod("01/01/"+cYear)
nReturn = dDate+1 - dStart
RETURN nReturn
*-- EoF: DoY()
FUNCTION WeekNo
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 11/14/1991
*-- Notes.......: Returns the week number of the year of a date (from beginning
*-- of the year).
*-- To use this function but start the week on a different day,
*-- change the 1 in the second-to-last line, the dow() of Sunday,
*-- to the dow() of the day that should start each week, 2 for
*-- Monday through 7 for Saturday.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/10/1991 - original function.
*-- 11/14/91 - Ken Mayer - expanded for readability ...
*-- Calls.......: DoY() Function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: WeekNo(<dDate>)
*-- Example.....: ?WeekNo({01/01/91})
*-- Returns.....: Numeric value of week number
*-- Parameters..: dDate = Date being tested for ...
*-------------------------------------------------------------------------------
parameters dDate
private dBaseDate,nReturn
dBaseDate = dDate - doy(dDate)
dBaseDate = dBaseDate - mod(dow(dBaseDate - 1), 7)
nReturn = int((dDate - dBaseDate) / 7)
RETURN nReturn
*-- EoF: WeekNo()
FUNCTION Holiday
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 04/22/1992
*-- Notes.......: Returns the date of a specific "floating" holiday (using
*-- chart below) for current year.
*-- Name Code
*-- President's Day P
*-- Daylight saving time D
*-- Memorial Day M
*-- Labor Day L
*-- Columbus Day C
*-- Resume Standard time S
*-- Election Day E
*-- Thanksgiving T
*-- Advent (1st Sunday) A
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/01/1991 - original function.
*-- 11/15/1991 - Ken Mayer - takes a code and year -- I basically
*-- simplified the use of the function.
*-- 04/22/1992 - Jay Parsons - added 'D' and 'S' options
*-- (daylight saving time and return to standard)
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: Holiday(<nYear>,"<cCode>")
*-- Example.....: ? Holiday(92,"P") && date of President's day, 1992
*-- Returns.....: Date of specified holiday ...
*-- Parameters..: nYear = Year you need the holiday date for ...
*-- cCode = one of the codes above for specific holiday
*-------------------------------------------------------------------------------
parameters nYear,cCode
private dBaseDate,cCode,cYear,nDoW,cFirst,dReturn
cCode = upper(cCode)
cYear = ltrim(str(nYear))
do case
case cCode = "P" && President's day (3rd Mon of Feb)
cFirst = "02/15/"
nDoW = 2
case cCode = "D" && Daylight time U.S. (1st Sun of April)
cFirst = "04/01/"
nDoW = 1
case cCode = "M" && Memorial day (last Mon of May)
cFirst = "05/25/"
nDoW = 2
case cCode = "L" && Labor day (1st Mon of Sep)
cFirst = "09/01/"
nDoW = 2
case cCode = "C" && Columbus Day (2nd Mon of Oct)
cFirst = "10/08/"
nDoW = 2
case cCode = "S" && Standard Time U.S. (Last Sun of Oct)
cFirst = "10/25/"
nDoW = 1
case cCode = "E" && Election Day (1st Tues of Nov not Nov 1)
cFirst = "11/02/"
nDoW = 3
case cCode = "T" && Thanksgiving (fourth Thursday of Nov)
cFirst = "11/22/"
nDoW = 5
case cCode = "A" && 1st Sun of Advent (Sunday closest Nov 30)
cFirst = "11/27/"
nDoW = 1
otherwise
return {} && if not one of above, return blank date ...
endcase
dFirst = ctod(cFirst + cYear)
dBaseDate = dFirst + 7 - nDow
dReturn = dBaseDate - dow( dBaseDate ) + nDow && dow( dBaseDate )
RETURN dReturn
*-- EoF: Holiday()
FUNCTION EasterDay
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (USSBBS, CIS 70160,340)
*-- Date........: 12/03/1992
*-- Notes.......: Returns date of Easter for given year after 1582.
*-- This gives the date of Easter as celebrated by Western
*-- churches. The algorithm is from Example 1.3.2.14 of
*-- Volume I of "The Art of Computer Programming", 2nd
*-- Edition, Addison-Wesley, Reading, MA, 1973, by Donald
*-- Knuth, who attributes it to Aloysius Lilius of Naples
*-- and Christopher Clavius of Germany, both floruit 1582.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/18/1991 - original function.
*-- 04/22/1992 - Jay Parsons - Notes expanded.
*-- 11/20/1992 - David Love - Added the private variable lYear
*-- 12/03/1992 - Jay Parsons - renamed lYear to nYr, dPascMoon
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: EasterDay(<Year>)
*-- Example.....: EasterDay(91)
*-- Returns.....: Date (in dBASE date format) of Easter
*-- Parameters..: nYear = Numeric form of year - YYYY or YY format
*-------------------------------------------------------------------------------
parameters nYear
private nYr,nGolden,nCentury,nNoLeap,nMoonOrbit,nEPact,dPascMoon,dReturn
*-- deal with two digit year ...
nYr = nYear
if nYr < 100
nYr = nYr + 100 * int(year(date())/100)
endif
nGolden = 1+mod(nYr,19)
nCentury = floor(nYr/100)+1
nNoLeap = floor(3*nCentury/4)-12
nMoonOrbit = floor((8*nCentury+5)/25)-5
nEPact = mod(11*nGolden+nMoonOrbit-nNoLeap+20,30)
nEPact = nEPact+iif(nEPact=24.or.(nEPact=25.and.nGolden>11),1,0)
dPascMoon = ctod("03/21/"+str(nYr)+mod(53-nEPact,30))
dReturn = dPascMoon+8-dow(dPascMoon)
RETURN dReturn
*-- EoF: EasterDay()
FUNCTION nDoW
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 04/22/1992
*-- Notes.......: Numeric Day of Week -- returns the numeric value of the
*-- day of week for use by some of the other date functions
*-- below.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/25/1992 - original function.
*-- 04/22/1992 - Jay Parsons - modified example/descriptions,
*-- added ltrim() of argument.
*-- Calls.......: None
*-- Called by...: None
*-- Usage.......: nDoW(<cDay>)
*-- Example.....: nDay = nDoW("Tues")
*-- Returns.....: Numeric dow value of day of week given
*-- Parameters..: cDay -- Character memvar containing "day" of week ('MONDAY',
*-- etc ...)
*-------------------------------------------------------------------------------
parameter cDay
RETURN at(upper(left(ltrim(cDay),3))," SUN MON TUE WED THU FRI SAT")/4
*-- nDoW()
FUNCTION FWDoM
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 02/25/1992
*-- Notes.......: First Working Day of the Month -- originally I used Dan
*-- Madoni's stuff from Technotes, but Jay came along and pointed
*-- out an easier way to do this. SO, here we have a shorter,
*-- faster, FWDoM function. This returns the first WORKING
*-- day of the month.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/25/1992 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: FWDoM(<dDate>)
*-- Example.....: ? CDoW( FWDoM(DATE()) ) (character day of week ...)
*-- Returns.....: dBASE Date
*-- Parameters..: dDate -- date to work from ...
*-------------------------------------------------------------------------------
parameters dDate
private dReturn, nDay
dReturn = dDate - day(dDate) + 1
nDay = DoW(dReturn)
RETURN dReturn + iif(nDay=7,2,iif(nDow=1,1,0))
*-- EoF: FWDoM()
FUNCTION LWDoM
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 02/25/1992
*-- Notes.......: Last Working Day of the Month -- function from Jay (new
*-- version like FWDoM) to return the last working day of the
*-- month. Give a date, the function returns the last WORKING day
*-- of the month. This has a companion function, giving the
*-- FIRST working day (see above).
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/25/1992 -- Original Release
*-- Calls.......: LDOM() Function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: LWDoM(<dDate>)
*-- Example.....: ? LWDoM(DATE())
*-- Returns.....: dBASE Date
*-- Parameters..: dDate -- date to work from ...
*-------------------------------------------------------------------------------
parameters dDate
private dReturn, nDay
dReturn = ldom(dDate)
nDay = DoW(dReturn)
RETURN dReturn - iif(nDay=7,1,iif(nDay=1,2,0))
*-- EoF: LWDoM()
FUNCTION FDoD
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 02/25/1992
*-- Notes.......: First Day of Date. This function works to give the first
*-- date in a given month (using a date) that a specific day
*-- of the week occurs (i.e., first Monday of the month).
*-- It returns a blank date if the day of week doesn't match,
*-- but is not case sensitive. New, slimmer, sleeker version
*-- by Jay ...
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/25/1992 -- Original Release
*-- Calls.......: NDOW() Function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: FDoD(<dDate>,"<cDay>")
*-- Example.....: ? FDoD(DATE(),"Tuesday")
*-- Returns.....: dBASE Date
*-- Parameters..: dDate -- date to work from ...
*-- cDay -- Day of week to look for ...
*-------------------------------------------------------------------------------
parameters dDate, cDay
private dReturn, nDay
nDay = nDoW(cDay)
dReturn = dDate - day(dDate) + 1
RETURN dReturn + mod(nDay+7 - DoW(dReturn),7)
*-- EoF: FDoD()
FUNCTION LDoD
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 02/25/1992
*-- Notes.......: Last Day of Date. This function works to give the last
*-- date in a given month (using a date) that a specific day
*-- of the week occurs (i.e., last Monday of the month).
*-- It returns a blank date if the day of week doesn't match,
*-- but is not case sensitive. New version as FDoD() ...
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/25/1992 -- Original Release
*-- Calls.......: LDOM() Function in DATES.PRG
*-- NDOW() Function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: LDoD(<dDate>,"<cDay>")
*-- Example.....: ? LDoD(DATE(),"Tuesday")
*-- Returns.....: dBASE Date
*-- Parameters..: dDate -- date to work from ...
*-- cDay -- Day of week to look for ...
*-------------------------------------------------------------------------------
parameters dDate, cDay
private dReturn
nDay = nDoW(cDay)
dReturn = ldom(dDate)
RETURN dReturn - mod(dow(dReturn) + 7 - nDay,7)
*-- EoF: LDoD()
FUNCTION LDoM
*-------------------------------------------------------------------------------
*-- Programmer..: Ken Chan (HazMatZak)
*-- Date........: 02/26/1992
*-- Notes.......: Last Day of Month -- Zak wrote this one up as a MUCH shorter
*-- and more straightforward version of the one I did. >sigh<.
*-- This function returns the date of the last day of the month.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/26/1992 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: LDoM(<dDate>)
*-- Example.....: ? LDoM(DATE())
*-- Returns.....: dBASE Date
*-- Parameters..: dDate -- date to work from ...
*-------------------------------------------------------------------------------
parameter dDate
private dNxtMonth
dNxtMonth = dDate - day(dDate) + 45 && middle of next month
RETURN dNxtMonth - day(dNxtMonth)
*-- EoF: LDoM()
FUNCTION NumDoD
*-------------------------------------------------------------------------------
*-- Programmer..: Ken Mayer (CIS: 71333,1033)
*-- Date........: 02/24/1992
*-- Notes.......: This function will return the x daytype of a month.
*-- Example: what if you need the third Monday of the month?
*- Send to this function a date (any date) of the month,
*-- the number you need (first, second...) and the day you
*-- need. The function is not case specific.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/24/1992 -- Original Release
*-- Calls.......: FDOD() Function in DATES.PRG
*-- NDOW() Function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: NumDoD(<dDate>,<nDay>,<cDay>)
*-- Example.....: ?NumDoD({02/03/92},3,"Monday")
*-- Returns.....: Date
*-- Parameters..: dDate = Any date of the month (and year) needed
*-- nDay = Number of day you need (i.e., third cDay of month)
*-- cDay = Character value of day (Monday, Tuesday, etc.)
*-------------------------------------------------------------------------------
parameter dDate, nDay, cDay
private dReturn
dReturn = FDoD(dDate,cDay) && get the first day of this type of the month
if nDay > 1 && if it's greater than one, add 7 (1 week) for
&& required # ...
dReturn = dReturn + ((nDay-1)*7)
endif
RETURN dReturn
*-- EoF: NumDoD()
FUNCTION WDiF
*-------------------------------------------------------------------------------
*-- Programmer..: Martin Leon (HMAN)
*-- Date........: 12/12/1991
*-- Notes.......: This UDF is designed to return the first Working Day In the
*-- Future of a specific date, based on a # of days. For example,
*-- to return the first working day, 10 days from the current
*-- date, you can pass the parameters of DATE() and 10. If the
*-- date 10 days from today is a working day, that date is
*-- returned, otherwise, the function returns the next closest
*-- working day. You may, if you wish, use a database to
*-- store holidays. If you do, the database must be laid out
*-- with the following structure:
*-- HOLIDAYS.DBF
*-- Field name Field type MDX?
*-- HOLIDATE Date Y
*-- Once the UDF has been run, the database is left open in
*-- whatever work area it was opened. If another database was
*-- in use at the time of calling the UDF, it becomes the active
*-- database after the UDF is done. The reason for leaving the
*-- database open is that this speeds up the process when you
*-- call on the UDF several times in a row.
*-- To ensure that holidays are working properly, there are
*-- 3 assumptions made by this function, and all must be true.
*-- These are: 1) WDIF() assumes that your holidays database
*-- has an index tag on the HOLIDATE field, 2) there are no
*-- duplicate entries, and 3) none of the holidays in the data-
*-- base fall on a weekend date. A simple method for insuring
*-- the last is:
*-- USE Holidays
*-- DELETE FOR DOW( Holidate ) = 7 .or. DOW( Holidate ) = 1
*-- PACK
*-- If you do not have a Holidays database, this function will
*-- work fine ...
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 12/12/1991 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: WDIF(<dStart>,<nDays>)
*-- Example.....: ?WDiF(date(),10)
*-- Returns.....: dBASE date
*-- Parameters..: dStart = Date to start counting from
*-- nDays = Number of working days in the future ...
*-------------------------------------------------------------------------------
parameter dStart, nWDays
private nweeks, n, nXtraDays, nHDays, dReturn, cNear, cAlias, dTemp
store 0 to nweeks, n, nHDays, nXtraDays
store {} to dReturn, dTemp
store "" to cNear, cAlias
cNear = set("NEAR")
if nWDays = 0
RETURN 0
endif
if type("dStart") + type("nWDays") # "DN"
RETURN -1
endif
*-- Rough guestimate of future date within a week
nweeks = int( nWDays / 5 )
dReturn = dStart + (nweeks * 7)
*-- Left over number of days from integer division above
nXtraDays = mod( nWDays, 5 )
*-- Check to see if Holidays database is already in use. This is
*-- done so that we don't have to close and open the database for
*-- every call to this UDF. The first call opens it and subsequent
*-- calls select it as needed.
*-- Check all work areas for holidays database, starting with work
*-- area 10 since this is most likely where it was opened the
*-- first time.
n = 10
do while .not. "HOLIDAYS" $ alias( n )
n = n - 1
if n = 0
exit
endif
enddo
*-- If it is open, store current alias name and select holidays
*-- database.
if n # 0
cAlias = alias()
select (alias(n))
else
*-- If it isn't the currently selected database,
*-- make sure it exists and use it and select it.
if file( "HOLIDAYS.DBF" )
cAlias = alias()
use Holidays order Holidate in select()
select Holidays
endif
endif
*-- If it's active now ...
if alias() = "HOLIDAYS"
*-- make sure it's in Holidate order, and ...
if order() # "HOLIDATE"
set order to Holidate
endif
set near on
*-- count all records in holiday database that fall within the
*-- range of the starting date and the rough guestimate date.
seek dStart
*-- don't count starting day if it's in Holidays database.
if dStart = Holidate
skip
endif
scan while dReturn >= Holidate
nHDays = nHDays + 1
endscan
set near off
endif
*-- Add holidays to "left over" days from original guestimate
nXtraDays = nXtraDays + nHDays
*-- Add extra days one day at a time to the original guestimate,
*-- skipping over holidays and weekends.
do while nXtraDays > 0
dReturn = dReturn + 1
if alias() = "HOLIDAYS"
if seek(dReturn)
loop
endif
endif
if dow( dReturn ) = 7 .or. dow( dReturn ) = 1
loop
endif
nXtraDays = nXtraDays - 1
enddo
*-- If return date falls on Saturday or Sunday, "re-wind" to Friday.
dReturn = dReturn - ;
iif( dow( dReturn ) = 7, 1, iif( dow(dReturn) = 1, 2, 0 ))
*-- If another database was origally in use, make it the active
*-- database again.
if "" # cAlias
select (cAlias)
endif
*-- set NEAR back to what it was orginally.
set near &cNear
RETURN dReturn
*-- EoF: WDiF()
FUNCTION StoD
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 11/10/1991
*-- Notes.......: Convert string YYYYMMDD or YYMMDD to a date regardless of
*-- SET DATE.
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 11/10/1991 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: StoD("<cString>")
*-- Example.....: ?StoD("19910101")
*-- Returns.....: Date
*-- Parameters..: <cString> = Date string you wish converted to "normal" dBASE
*-- date. Must be in either YYYYMMDD or YYMMDD format.
*-------------------------------------------------------------------------------
parameters cString
private dTest, cMonth, cDay, cYear, dReturn
dTest = ctod("01/02/03")
if len(cString) < 8
cString = left(str(year(date()),4),2) + cString
endif
cYear = left(cString, 4)
cMonth = substr(cString, 5, 2)
cDay = right(cString, 2)
do case
case month(dTest) = 1
dReturn = ctod(cMonth + "/" + cDay + "/" + cYear)
case day(dTest) = 1
dReturn = ctod(cDay + "/" + cMonth + "/" + cYear)
otherwise
dReturn = ctod(cYear + "/" + cMonth + "/" + cDay)
endcase
RETURN dReturn
*-- EoF: StoD()
FUNCTION Quarter
*-------------------------------------------------------------------------------
*-- Programmer..: Bowen Moursund (CIS: 76566,1405)
*-- Date........: 02/03/1992
*-- Notes.......: Returns the quarter of the year of a specific date ...
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 02/03/1992 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: Quarter(<dDate>)
*-- Example.....: ?Quarter({05/25/1992})
*-- Returns.....: Numeric (integer) value from 1 to 4 (or 0 on error ...)
*-- Parameters..: dDate = date to be checked
*-------------------------------------------------------------------------------
Parameter dDate
RETURN iif(type("dDate")="D",ceiling(month(dDate)/3),0)
*-- EoF: Quarter()
FUNCTION Dat2Jul
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 03/01/1992
*-- Notes.......: Converts dBASE date to Julian # of days (from January 1,
*-- 4713 B.C.)
*-- Rev. History: 03/01/1992 -- Original Release
*-- Written for.: dBASE IV
*-- Rev. History: None
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: Dat2Jul("<dDate>")
*-- Example.....: ?Dat2Jul(date())
*-- Returns.....: Numeric
*-- Parameters..: dDate = Date to convert to Julian ...
*-------------------------------------------------------------------------------
PARAMETERS dDate
RETURN 2415386 + dDate - ctod( "01/01/01" )
*-- EoF: Dat2Jul()
FUNCTION Jul2Dat
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 03/01/1992
*-- Notes.......: Converts Julian # of days to dBASE Date
*-- Rev. History: 03/01/1992 -- Original Release
*-- Written for.: dBASE IV
*-- Rev. History: None
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: Jul2Dat(nJulian)
*-- Example.....: ?Jul2Dat(2448691)
*-- Returns.....: Date
*-- Parameters..: nJulian = Julian date to convert to dBase Date
*-------------------------------------------------------------------------------
parameters nJulian
RETURN ctod( "01/01/01" ) + (nJulian - 2415386)
*-- EoF: Jul2Dat()
FUNCTION DateSet
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (CIS: 70160,340)
*-- Date........: 03/01/1992
*-- Notes.......: Returns string giving name of current DATE format
*-- This is not needed in Version 1.5, in which set("DATE")
*-- returns the format. Unlike that function in 1.5, this
*-- one cannot distinguish between date formats set with
*-- different terms that amount to the same thing:
*-- DMY = BRITISH = FRENCH
*-- MDY = AMERICAN
*-- YMD = JAPAN
*-- If your users will be using one of these formats and
*-- are sensitive about the name, substitute the one they
*-- want for the equivalent in this function.
*-- Rev. History: 03/01/1992 -- Original Release
*-- Written for.: dBASE IV, versions below 1.5
*-- Rev. History: None
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: DateSet()
*-- Example.....: ?DateSet()
*-- Returns.....: Character
*-- Parameters..: None
*-------------------------------------------------------------------------------
private cCent, cTestdate, cDelimiter
cCent = set( "CENTURY" )
set century off
cTestdate = ctod( "01/02/03" )
cDelimiter = substr( dtoc( cTestdate ), 3, 1 )
set century &cCent
do case
case month( cTestdate ) = 1
RETURN iif( cDelimiter = "-", "USA", "MDY" )
case day( cTestdate ) = 1
RETURN iif( cDelimiter = "/", "DMY", ;
iif( cDelimiter = ".", "GERMAN", "ITALIAN" ) )
otherwise
RETURN iif( cDelimiter = ".", "ANSI", "YMD" )
endcase
*-- EoF: DateSet()
FUNCTION FrstNxtMth
*-------------------------------------------------------------------------------
*-- Programmer..: Todd Barry (TODDBARRY)
*-- Date........: 04/04/1992
*-- Notes.......: Returns first day of next month
*-- Written for.: dBASE IV, 1.1
*-- Rev. History: 04/04/1992 -- Original Release
*-- 02/25/1993 -- Shorted by Jay Parsons, based on Zak's LDOM()
*-- function.
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: FrstNxtMth(<dDate>)
*-- Example.....: FrstNxtMth( dDate )
*-- Returns.....: dBASE Date
*-- Parameters..: dDate -- date to work from ...
*-------------------------------------------------------------------------------
parameters dDate
private dReturn
dReturn = dDate - day(dDate) + 45
RETURN dReturn - day(dReturn) + 1
*-- EoF: FrstNxtMth()
FUNCTION FDoM
*-------------------------------------------------------------------------------
*-- Programmer..: Kenneth Chan [ZAK] (CIS: 71542,2712)
*-- Date........: 01/05/1993
*-- Notes.......: First Day of Month
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 01/05/1993 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: FDoM(<dArg>)
*-- Example.....: ?FDOM(date())
*-- Returns.....: Date
*-- Parameters..: dArg = a Date argument -- function returns first day of the
*-- month of this date.
*-------------------------------------------------------------------------------
parameter dArg
RETURN dArg - day( dArg ) + 1
*-- EoF: FDoM()
FUNCTION FDoY
*-------------------------------------------------------------------------------
*-- Programmer..: Kenneth Chan [ZAK] (CIS: 71542,2712)
*-- Date........: 01/05/1993
*-- Notes.......: Returns January 1 of the year of the date argument passed
*-- to it.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 01/05/1993 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: FDoY(<dArg>))
*-- Example.....: FDoY(DATE())
*-- Returns.....: January 1 of the year in dArg
*-- Parameters..: dArg = date data
*-------------------------------------------------------------------------------
parameter dArg
private dJan
dJan = dArg - day( dArg ) + 1 - 28 * ( month( dArg ) - 1 )
RETURN dJan - day( dJan ) + 1
*-- EoF: FDoY()
FUNCTION LDoY
*-------------------------------------------------------------------------------
*-- Programmer..: Kenneth Chan [ZAK] (CIS: 71542,2712)
*-- Date........: 01/05/1993
*-- Notes.......: Returns December 31 of year in date argument passed to
*-- function.
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 01/05/1993 -- Original Release
*-- Calls.......: LDoM() Function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: LDoY(<dArg>)
*-- Example.....: ?LDoY(Date())
*-- Returns.....: Last Day of Year
*-- Parameters..: dArg = Date
*-------------------------------------------------------------------------------
parameter dArg
private dDec
dDec = dArg - day( dArg ) + 28 * ( 13 - month( dArg ))
RETURN LDoM( dDec )
*-- EoF: LDoY()
FUNCTION QDate
*-------------------------------------------------------------------------------
*-- Programmer..: Kenneth Chan [Zak] (CIS:71542,2712)
*-- Date........: 01/05/1993
*-- Notes.......: Quicken-style dates
*-- Works best when BELL is OFF and CONFIRM is ON
*-- Works with any SET DATE format
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 01/05/1993 1.0
*-- Calls.......: FDoM() Function in DATES.PRG
*-- LDoM() Function in DATES.PRG
*-- FDoY() Function in DATES.PRG
*-- LDoY() Function in DATES.PRG
*-- Strip() Function in STRINGS.PRG
*-- Called by...: WHEN clause of GET
*-- Usage.......: @ ... GET <dArg> ... WHEN QDate( <dArg> ) ....
*--
*-- Key Function
*-- --- --------
*-- T Today's date
*-- - or _ Day before
*-- + or = Day after
*-- M First day of month | Repeated keypress will
*-- H Last day of month | give you previous/next
*-- Y First day of year | month/year
*-- R Last day of year |
*-- digit Begin manual date entry
*--
*-- Example.....: dFoo = date()
*-- @ 10,10 get dFoo when QDate( dFoo )
*-- Returns.....: .T.
*-- Parameters..: dArg = Date variable/field you're GETting
*-------------------------------------------------------------------------------
parameter dArg
private lLoop, nRow, nCol, lConfirmOn, nKey, cLastKey, cSimKey
lLoop = .t.
nRow = row()
nCol = col()
lConfirmOn = ( set( "CONFIRM" ) = "ON" )
cLastKey = ""
cSimKey = ""
*-- Save screen in case of Esc
save screen to sQDate
*-- Check for skip flag (used when SET CONFIRM is ON)
if type( "x__QDate" ) # "U"
release x__QDate
else
do while lLoop
*-- Display current date in special color
@ nRow, nCol say dArg color gb+/n && <-- use your own color ...
*-- Move cursor to beginning of date
@ nRow, nCol say ""
*-- Wait for a keypress
nKey = inkey( 0 )
*-- Convert to uppercase; ignore keys with negative INKEY() values
cKey = upper( chr( max( nKey, 0 )))
do case
case cKey = "T" && Today
dArg = date()
case cKey = "-" .or. cKey = "_" && The day before
dArg = dArg - 1
case cKey = "+" .or. cKey = "=" && The day after
dArg = dArg + 1
case cKey = "M" && First day of the month
dArg = FDoM( iif( cLastKey = "M", dArg - 1, dArg))
case cKey = "H" && Last day of the month
dArg = LDoM( iif( cLastKey = "H", dArg + 1, dArg))
case cKey = "Y" && First day of the year
dArg = FDoY( iif( cLastKey = "Y", dArg - 1, dArg))
case cKey = "R" && Last day of the year
dArg = LDoY( iif( cLastKey = "R", dArg + 1, dArg))
case cKey $ "0123456789" && Digit -- manual date entry
lLoop = .f.
*-- Clear entry and start at beginning
keyboard chr( 25 ) + chr( 26 ) + cKey
case nKey >= 32 .and. nKey < 127 .or. nKey > 127
*-- Ignore invalid keys, like letters and symbols
case nKey = 27 .or. nKey = 17 && Esc or Ctrl-Q
lLoop = .f.
*-- Restore screen and quit
restore screen from sQDate
keyboard cKey
otherwise
lLoop = .f.
*-- Figure out how to simulate last keypress
*-- If SET CONFIRM is OFF
if .not. lConfirmOn
*-- Go back up to date field
cSimKey = "{UP}" && Up arrow
*-- Create flag variable to skip routine
public x__QDate
endif
cSimKey = cSimKey + "{HOME}"
*-- Recreate keypress
do case
case nKey = -400
cSimKey = cSimKey + "{BACKTAB}"
otherwise
cSimKey = cSimKey + cKey
endcase
*-- Clear entry and "type in" date without separators
*-- And simulate last keypress
keyboard "{HOME}{CTRL-Y}" + ;
Strip( dtoc( dArg ), left( ltrim( dtoc( {} )), 1)) + cSimKey
endcase
*-- Save key just pressed
cLastKey = cKey
enddo
endif
*-- release the screen from memory before returning
release screen sQDate
RETURN .t.
*-- EoF: QDate()
*-------------------------------------------------------------------------------
*-- For more details on the Hebrew Date routines, see the file attached
*-- called SHANA.TXT, written by Jay Parsons to help explain things.
*-------------------------------------------------------------------------------
FUNCTION Hebrewdate
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/27/1993
*-- Notes.......: Converts a date to corresponding date on the Hebrew
*-- calendar. The date returned is the Hebrew date that
*-- matches the daylight hours of the given civil date;
*-- the Hebrew date actually starts the evening before.
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/27/1993 -- Original
*-- Calls.......: Dat2Heb() function in DATES.PRG
*-- IsLeapH() function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: Hebrewdate( <dDate> )
*-- Example.....: ? Hebrewdate( {03/27/93} )
*-- Returns.....: a character string giving the month, day and year of
*-- the date, such as "Nisan 5, 5753"
*-- Parameters..: dDate = a dBASE date
*-------------------------------------------------------------------------------
parameters dDate
private cDate, cMonths, nMo, cMo, nDay, cDay, nYear
* ruler -> 012345678901234567890123456789012345678901
cMonths = "Tishri HeshvanKislev Tebeth Shebat Adar " + ;
"Nisan Iyar Sivan Tammuz Ab Ellul "
cDate = Dat2Heb( dDate )
nYear = val( right( cDate, 4 ) )
nMo = val( left( cDate, 2 ) )
nDay = val( substr( cDate, 4, 2 ) )
do case
case nMo < 6 .or. .not. IsLeapH( nYear )
cMo = trim( substr( cMonths, 7 * ( nMo - 1 ) + 1, 7 ) )
case nMo > 7
cMo = trim( substr( cMonths, 7 * ( nMo - 2 ) + 1, 7 ) )
otherwise
cMo = iif( nMo = 6, "First ", "Second " ) + "Adar"
endcase
RETURN cMo + " " + ltrim( str( nDay, 2 ) ) + ", " + right( cDate, 4 )
*-- EoF: HebrewDate()
FUNCTION Civildate
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/27/1993
*-- Notes.......: Converts a Hebrew calendar date to corresponding date
*-- on the civil calendar. The date returned is the civil
*-- date that matches the daylight hours of the given Hebrew
*-- date; the Hebrew day actually starts the evening before.
*-- Supplying the function with a nonexistent 30th day of
*-- Heshvan or Kishlev is fairly harmless; it will return the
*-- civil date of the first of the following month, the
*-- correct date to celebrate a birthday falling on the date
*-- that does not exist in the given year. This is **NOT**
*-- sufficient to avoid problems with Adar, or with Yahrzeit
*-- for deaths occurring on Heshvan 30 or Kishlev 30; users
*-- are cautioned against finding anniversaries in those cases
*-- by supplying the Hebrew month and date of the event and
*-- a different Hebrew year as parameters to this function.
*-- In general, reconverting the civil date returned
*-- to a Hebrew date and comparing it to the original Hebrew
*-- date furnished to this function will disclose any possible
*-- problems, as the two Hebrew dates will not match.
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/27/1993 -- Original
*-- Calls.......: Kebiah() function in DATES.PRG
*-- Roshashana() function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: Civildate(<cDate> )
*-- Example.....: ? Civildate( "05/07/5753" )
*-- Returns.....: dBase date, the corresponding civil date.
*-- Parameters..: cDate = character string holding month, day and year
*-- of Hebrew date, MM/DD/YYYY. Month must be
*-- in range 1-13 and must correspond to month
*-- order in the particular year--that is, "12"
*-- signifies Ab in a leap year but Ellul in a
*-- common year.
*-------------------------------------------------------------------------------
parameters cDate
private nMo, nDay, nYear, dDate, cKebiah, aDays
nYear = val( right( cDate, 4 ) )
nMo = val( left( cDate, 2 ) )
nDay = val( substr( cDate, 4, 2 ) )
dDate = Roshashana( nYear ) - 1
cKebiah = Kebiah( dDate + 1, Roshashana( nYear + 1 ) )
declare aDays[ 13 ]
aDays[ 1 ] = 30
aDays[ 2 ] = iif( cKebiah $ "EFGLMN", 30, 29 )
aDays[ 3 ] = iif( cKebiah $ "ABHIJ", 29, 30 )
aDays[ 4 ] = 29
aDays[ 5 ] = 30
if cKebiah > "G"
aDays[ 6 ] = 30
aDays[ 7 ] = 29
nX = 7
else
aDays[ 6 ] = 29
nX = 6
endif
nY = 1
do while nY < 7
aDays[ nX + nY ] = 29 + mod( nY, 2 )
nY = nY + 1
enddo
nX = 1
do while nX < nMo
dDate = dDate + aDays[ nX ]
nX = nX + 1
enddo
RETURN dDate + nDay
*-- EoF: Civildate()
FUNCTION Dat2Heb
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/27/1993
*-- Notes.......: Converts a date to corresponding date on the Hebrew
*-- calendar. The date returned is the Hebrew date that
*-- matches the daylight hours of the given civil date;
*-- the Hebrew date actually starts the evening before.
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/27/1993
*-- Calls.......: Kebiah() function in DATES.PRG
*-- Roshashana() function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: Dat2Heb( <dDate> )
*-- Example.....: ? Dat2Heb( {03/27/93} )
*-- Returns.....: a character string giving the month, day and year of
*-- the date in numerals, such as "07/05/5753"
*-- Parameters..: dDate = a dBASE civil date to convert
*-------------------------------------------------------------------------------
parameters dDate
private nYear, dFirst, dSecond, cKebiah, aDays, nX, nY, nDay
nYear = year( dDate ) + 3761
dFirst = Roshashana( nYear )
if dFirst > dDate
nYear = nYear - 1
dSecond = dFirst
dFirst = Roshashana( nYear )
else
dSecond = Roshashana( nYear + 1 )
endif
nDay = 1 + dDate - dFirst
cKebiah = Kebiah( dFirst, dSecond )
declare aDays[ 13 ]
aDays[ 1 ] = 30
aDays[ 2 ] = iif( cKebiah $ "EFGLMN", 30, 29 )
aDays[ 3 ] = iif( cKebiah $ "ABHIJ", 29, 30 )
aDays[ 4 ] = 29
aDays[ 5 ] = 30
aDays[ 6 ] = iif( cKebiah > "G", 30, 29 )
if cKebiah > "G"
aDays[ 7 ] = 29
nX = 7
else
nX = 6
endif
nY = 1
do while nY < 7
aDays[ nX + nY ] = 29 + mod( nY, 2 )
nY = nY + 1
enddo
nX = 1
do while nDay > aDays[ nX ]
nDay = nDay - aDays[ nX ]
nX = nX + 1
enddo
RETURN right( str( nX + 100, 3 ), 2 ) + "/" + right( str( nDay + 100, 3 ), 2 ) ;
+ "/" + str( nYear, 4 )
*-- EoF: Dat2Heb()
FUNCTION Kebiah
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/26/1993
*-- Notes.......: Kebiah of a year, using Arthur Spier's notation.
*-- This tells whether the year in the Hebrew calendar is
*-- defective, regular or excessive and whether or not a
*-- leap year. In order to limit the recalculations of Rosh
*-- Hashanah in date conversions that would be needed if this
*-- function were called with the year only, it requires the
*-- civil dates of the two Rosh Hashanahs at start and end as
*-- parameters.
*-- Error checking is limited to determining whether the
*-- days of the week of the two dates given and number of
*-- days between them are possible; no check is made that
*-- either is the correct date of Rosh Hashanah.
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: Kebiah(<dRosh1>,dRosh2>)
*-- Example.....: c = Kebiah( {09/16/1993},{09/06/1994} )
*-- Returns.....: a letter from A through N, signifying as follows:
*-- A - G common year of 12 months
*-- H - N leap year of 13 months
*-- First day of length and type First day of
*-- Rosh Hashanah of year Passover
*-- A Monday 353 days, defective Tuesday
*-- B Sabbath 353 days, defective Sunday
*-- C Tuesday 354 days, regular Thursday
*-- D Thursday 354 days, regular Sabbath
*-- E Monday 355 days, excessive Thursday
*-- F Thursday 355 days, excessive Sunday
*-- G Sabbath 355 days, excessive Tuesday
*-- H Monday 383 days, defective Thursday
*-- I Thursday 383 days, defective Sunday
*-- J Sabbath 383 days, defective Tuesday
*-- K Tuesday 384 days, regular Sabbath
*-- L Monday 385 days, excessive Sabbath
*-- M Thursday 385 days, excessive Tuesday
*-- N Sabbath 385 days, excessive Thursday
*-- or "" signifying error in dates passed to function.
*-- Parameters..: dRosh1 = civil date of Rosh Hashanah starting the year
*-- dRosh2 = civil date of Rosh Hashanah starting the
*-- following year
*-------------------------------------------------------------------------------
parameters dRosh1, dRosh2
private dR1, dR2, nDays, nDow, cRet
dR1 = min( dRosh1, dRosh2 )
dR2 = max( dRosh1, dRosh2 )
nDays = dR2 - dR1
nDow = dow( dR2 )
if nDow = 1 .or. nDow = 4 .or. nDow = 6 && if dR2 is Sun, Wed or Fri
RETURN ""
endif
cRet = space( 7 ) && will return "" if too few or too many days
do case
* Days SMTWHFS && if the portion of a cRet string below a day
* Dows 1234567 && of the week is blank, can't be Rosh Hashanah
case nDays = 353
cRet = " A B"
case nDays = 354
cRet = " C D "
case nDays = 355
cRet = " E F G"
case nDays = 383
cRet = " H I J"
case nDays = 384
cRet = " K "
case nDays = 385
cRet = " L M N"
endcase
RETURN trim( substr( cRet, dow( dR1 ), 1 ) )
*-- EoF: Kebiah()
FUNCTION Roshashana
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/26/1993
*-- Notes.......: Returns date of Rosh Hashanah of the given Hebrew year.
*-- To find date when Rosh Hashanah occurs in a C.E. year,
*-- add 3761 to the C.E. Year. This formidable-looking
*-- procedure is actually a straightforward matter of using the
*-- date and time of one Molad Tishri, the moment of new moon
*-- starting a year, and advancing or setting back that date
*-- and time by the number of days, hours and chalokim in each
*-- period of 19 years, then by the number in each month within
*-- the balance of the years. Since we are concerned only with
*-- the molads, we need not worry about the number of days in
*-- the calendar months, but only with the lunar period of 29
*-- days, 12 hours and 793 chalokim and the number of months,
*-- giving effect to leap years.
*-- A chelek, plural chalokim, is 1/1080 of an hour, or
*-- 3 1/3 seconds, and is traditionally used for these
*-- calculations, in part because it avoids the need to deal
*-- with fractions.
*-- Finally, having determined the civil date of the Molad
*-- Tishri of the proper year and the hour and chalokim within
*-- the date, we call a separate function to determine the
*-- applicability of the dechiyoth or postponements that may
*-- cause Rosh Hashanah to be pushed to a later date.
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/26/1993
*-- Calls.......: NormalH procedure in DATES.PRG
*-- Dechiyoth function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: Roshashana( <nYear> )
*-- Example.....: Roshashana( 1993 + 3761 )
*-- Returns.....: date = civil date of Rosh Hashanah in the given year
*-- Parameters..: nYear = number of year in the Hebrew calendar
*-------------------------------------------------------------------------------
parameters nYear
private dMoldate, nMolhr, nMolch, nYrs, nMoons
* we use the Molad of Tishri 5739, October 2, 1978, as the base date
* for no particular reason except it started the most recent cycle.
dMoldate = { 10/02/1978 } && The Hebrew date started 6 p.m. Oct. 1.
nMolhr = 11 && The molad fell 11 hours and 614 chalokim
nMolch = 614 && later into the day.
nYrs = nYear - 5739 && years of difference to adjust.
* adjust for each full 19-year cycle ( machzor koton )
* if adjusting backward, go to beginning of the cycle in which is
* the specified year
nCycles = floor( nYrs / 19 )
dMoldate = dMoldate + 6939 * nCycles
nMolhr = nMolhr + 16 * nCycles
nMolch = nMolch + 595 * nCycles
* adjust for leftover months within the cycle; the formula was
* hacked to return the correct number of months for any number
* of years from 0 through 19 at the beginning of a 19-year cycle.
nYrs = nYrs - 19 * nCycles
nMoons = int( .01 + nYrs * 12.374 )
dMoldate = dMoldate + 29 * nMoons && length of a lunar month,
nMolhr = nMolhr + 12 * nMoons && 29 days, 12 hours and
nMolch = nMolch + 793 * nMoons && 793 chalokim
do NormalH with dMoldate, nMolhr, nMolch
RETURN dMoldate + Dechiyoth( dMolDate, nMolhr, nMolch )
*-- EoF: Roshashana()
FUNCTION Dechiyoth
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/26/1993
*-- Notes.......: Adjusts date of Rosh Hashanah for the four dechiyoth
*-- ( postponements ) required to regularize the calendar and
*-- prevent either two days in a row of Sabbath at Yom Kippur
*-- or Hoshanah Rabbah being on the Sabbath.
*-- Days, hours and chalokim are measured from 6 p.m.
*-- Friday evening, considered the beginning of the Sabbath for
*-- calendar purposes.
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/26/1993
*-- Calls.......: IsLeapH function in DATES.PRG
*-- Called by...: Any
*-- Usage.......: Dechiyoth( <dDate>, <nHrs>, <nChalokim> )
*-- Example.....: nDay = Dechiyoth( {10/02/1978}, 11, 614 )
*-- Returns.....: date = civil date of Rosh Hashanah
*-- Parameters..: dDate = civil date of Molad Tishri
*-- nHrs = Hebrew hour of Molad Tishri ( past 6. p.m. )
*-- nChalokim = chalokim past the hour of Molad Tishri
*-------------------------------------------------------------------------------
parameters dDate, nHrs, nChalokim
private nMoldow, nFirst, nNidcheh
nMoldow = mod( dow( dDate ), 7 )
nNidcheh = 0
nFirst = nMoldow
* 1) if Molad Tishri is after noon, new moon could not be seen anywhere
* that day, so Rosh Hashanah is nidcheh ( pushed off ) to next day
if nHrs * 1080 + nChalokim > 18 * 1080
nNidcheh = 1
nFirst = nFirst + 1
endif
* 2) if Rosh Hashanah would be Sunday, Wednesday or Friday, it is
* nidcheh ( again if dechiyah 1 applied ) so that Yom Kippur will not
* fall on Friday or Sunday, nor Hoshanah Rabbah on the Sabbath.
if nFirst = 1 .or. nFirst = 4 .or. nFirst = 6
nNidcheh = nNidcheh + 1
endif
* 3) if Molad Tishri in a common year is Tuesday and the next
* Molad Tishri would be after noon of the Sabbath, this Rosh Hashanah
* is nidcheh twice so the next Rosh Hashanah will not have to be--
* the result would be that this year would have 356 days, too many.
if .not. IsLeapH( year( dDate ) + 3761 ) .and. nMoldow = 3 ;
.and. 1080 * nHrs + nChalokim > 9 * 1080 + 204 && 9hrs 204
nNidcheh = 2
endif
* 4) if Molad Tishri in a common year following a leap year occurs
* Monday morning so late that the preceding leap year must have
* started on Thursday, this Rosh Hashanah is nidcheh so the preceding
* leap year will not be left with 382 days, too few.
if IsLeapH( year( dDate ) + 3760 ) .and. nMoldow = 2 ;
.and. 1080 * nHrs + nChalokim > 15 * 1080 + 589 && 15 hrs 589
nNidcheh = 1
endif
RETURN nNidcheh
*-- EoF: Dechiyoth()
FUNCTION IsLeapH
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/27/1993
*-- Notes.......: Returns .T. or .F. whether a Hebrew year is a leap year.
*-- The formula is a hack; it returns .T. when the position of
*-- the year in the cycle is 3, 6, 8, 11, 14, 17 or 19 ( the
*-- last, because its modulus 19 is 0. )
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/27/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: IsLeapH( <nYear> )
*-- Example.....: ? IsLeapH( 1993 + 3761 )
*-- Returns.....: logical = true if the year is a leap year, or false
*-- Parameters..: nYear = number of the year on the Hebrew calendar
*-------------------------------------------------------------------------------
parameters nYear
private nY
nY = mod( nYear, 19 )
RETURN mod( nY + int( ( nY + 3 ) / 11 ), 3 ) = 0
*-- EoF: IsLeapH()
PROCEDURE NormalH
*-------------------------------------------------------------------------------
*-- Programmer..: Jay Parsons (Compuserve 70160,340)
*-- Date........: 03/26/1993
*-- Notes.......: Normalize date and numbers of hours and chalokim
*-- Written for.: dBASE IV, 2.0
*-- Rev. History: 03/26/1993 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: DO NormalH with <dDate>, <nHrs>, <nChalokim>
*-- Example.....: DO Normalh with { 03/13/1993}, 39, 1452
*-- Parameters..: dDate = a dBASE civil date
*-- nHrs = number of hours
*-- nChalokim = number of chalokim
*-- Side Effects: This procedure changes its parameters.
*-------------------------------------------------------------------------------
parameters dDate, nHrs, nChalokim
nHrs = nHrs + floor( nChalokim / 1080 )
nChalokim = mod( nChalokim, 1080 )
dDate = dDate + floor( nHrs / 24 )
nHrs = mod( nHrs, 24 )
RETURN
*-- EoP: NormalH
FUNCTION MDY_UDF
*-------------------------------------------------------------------------------
*-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
*-- Date........: 11/25/1992
*-- Note........: Print date nicely, regardless of SET CENTURY setting
*-- : MDY({01/01/80}) prints as "January 01, 80"
*-- : MDY_UDF({01/01/80}) prints as "January 1, 1980"
*-- Written for.: dBASE IV 1.5+
*-- Rev. History: 11/25/1992 -- Original
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: MDY_UDF(<dDate>)
*-- Example.....: ? MDY_Udf(ctod("01/01/92"))
*-- Returns.....: character representation of current date
*-- Parameters..: dDate = date to modify
*-------------------------------------------------------------------------------
parameters dDate
if .not. IsBlank(dDate)
return cmonth(dDate)+" "+iif(day(dDate)<10,str(day(dDate),1),;
str(day(dDate),2))+", "+str(year(dDate),4)
else
return ""
endif
*-- EoF: MDY_UDF()
*--------------------------------------------------------------------------
*-- Strip() is here from STRINGS.PRG to make life a bit easier ...
*--------------------------------------------------------------------------
FUNCTION Strip
*-------------------------------------------------------------------------------
*-- Programmer..: Kenneth Chan [ZAK] (CIS: 71542,2712)
*-- Date........: 01/05/1993
*-- Notes.......: Strips out specified character(s) from a string
*-- Written for.: dBASE IV, 1.5
*-- Rev. History: 01/05/1993 -- Original Release
*-- Calls.......: None
*-- Called by...: Any
*-- Usage.......: Strip(<cVar>,<cArg>)
*-- Example.....: ?strip(dtoc(date(),"/")
*-- Returns.....: Character
*-- Parameters..: cVar = variable/field to remove character(s) from
*-- cArg = item to remove from cVar
*-------------------------------------------------------------------------------
parameter cVar, cArg
do while cArg $ cVar
cVar = stuff( cVar, at( cArg, cVar ), 1, "" )
enddo
RETURN cVar
*-- EoF: Strip()
*-------------------------------------------------------------------------------
*-- EoP: DATES.PRG
*-------------------------------------------------------------------------------