I need to calculate the date between two dates, and tell me how many day are in between, if more than 30 days then I will target something.
in this script D is the date (in the past) that I want to calculate from today
set X to MYdatefromSafari -- "August 26th, 2016"
set D to ConvertDate(X)
log D
on ConvertDate(X) -- sub routine to convert string "english_month dayth/st, year" to real date
set MS to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
set LW to every word of X
if (count of LW) is not 3 then return "" -- invalid format
set MI to 0 -- check month : should be in the list
repeat with I from 1 to 12
if item I of MS is item 1 of LW then set MI to I
end repeat
if MI is 0 then return "" -- the fisrt word is not in the list of months
try -- check day : it should be NNth of NNst
set DI to (text 1 thru -3 of item 2 of LW) as integer
end try
if not ((DI > 0) and (DI < 31)) then return "" -- invalid day
try -- check year
set YI to (item 3 of LW) as integer
end try
if not ((YI > 0) and (YI < 9999)) then return "" -- invalid year
return date ((DI & "/" & MI & "/" & YI) as string)
end ConvertDate
In the best scenario, that would calculate the number of date in between if less than a year, and month or year if more
EDIT :
set X to "August 26th, 2016"
set MyDate to ConvertDate(X)
set D to ConvertDate(X)
log D
set SecondDate to (current date) -- = system date
set ListDiff to DateDiff(D, CD) -- returns {diff days, diff months, diff years}
log "Days = " & item 1 of ListDiff
log "Months = " & item 2 of ListDiff
log "Years = " & item 3 of ListDiff
on DateDiff(D1, D2) -- return list with difference in days, in months, in years
-- depending if differences is less than month, or less than year or higher than a year
if D1 > D2 then -- set DStart as oldest date
copy {D1, D2} to {Dend, DStart}
else
copy {D1, D2} to {DStart, Dend}
end if
return {(Dend - DStart) div days, (Dend - DStart) div (30 * days), (Dend - DStart) div (365 * days)}
end DateDiff
on ConvertDate(X) -- sub routine to convert string "english_month dayth/st, year" to real date
set MS to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
set LW to every word of X
if (count of LW) is not 3 then return "" -- invalid format
set MI to 0 -- check month : should be in the list
repeat with I from 1 to 12
if item I of MS is item 1 of LW then set MI to I
end repeat
if MI is 0 then return "" -- the fisrt word is not in the list of months
try -- check day : it should be NNth of NNst
set DI to (text 1 thru -3 of item 2 of LW) as integer
end try
if not ((DI > 0) and (DI < 31)) then return "" -- invalid day
try -- check year
set YI to (item 3 of LW) as integer
end try
if not ((YI > 0) and (YI < 9999)) then return "" -- invalid year
return date ((DI & "/" & MI & "/" & YI) as string)
end ConvertDate
Sub-routine "DateDiff" bellow gives back a list of 3 difference values : in days, months and years.
Set X to MyDatefrom Safari
Set MyDate to ConvertDate(X)
set SecondDate to (current date) -- = system date
set ListDiff to DateDiff(D, CD) -- returns {diff days, diff months, diff years}
log "Days = " & item 1 of ListDiff
log "Months = " & item 2 of ListDiff
log "Years = " & item 3 of ListDiff
on DateDiff(D1, D2) -- return list with difference in days, in months, in years
-- depending if differences is less than month, or less than year or higher than a year
if D1 > D2 then -- set DStart as oldest date
copy {D1, D2} to {Dend, DStart}
else
copy {D1, D2} to {DStart, Dend}
end if
return {(Dend - DStart) div days, (Dend - DStart) div (30 * days), (Dend - DStart) div (365 * days)}
end DateDiff
on ConvertDate(X) -- copy your existing sub-routine
end ConvertDate
For instance if MyDate = Jan 20th 2016 and we are August 26th 2016, it will return {219, 7, 0} because différence is 216 days or 7 months (Jan to August) or 0 year (2016 both dates !).
Related
In Stata I am trying to assess which of the given birthdays is the next one compared with a given date. My data looks like this:
All dates are in daily format (%dD_m_Y), e.g. 18mar1926
Variable date which is the reference date with which all other dates should be compared
Variables birth1, birth2, birth3, birth4, birth5, birth6 contain the birthday of all possible household members.
For example: A household with two adults A and B. The birthday of A is 20th Nov 1977 and the birthday of person B is 30th March 1978. The reference date is 29.11.2020. I want to know who is the person who has the next birthday, in the example above it is person B, because person A has had its birthday one week before the reference date, so the next birthday in this household will be celebrated on the 30 March 2021.
Example data:
date
birth1
birth2
birth3
birth4
birth5
birth6
02feb2021
15jan1974
27nov1985
30nov2020
31aug1945
27jun1999
07apr1997
19nov2020
27sep1993
30dec1996
29jan2021
29mar1973
05dec2020
21jan1976
02oct1976
21jan1976
25may1995
15feb1997
25nov2020
25nov1943
29nov1946
02feb2021
28apr1979
EDITED to account for Feb 29
*The edit will treat people who have a February 29 birthday as if it were March 1 in cases when the year of date is not a leap year. If that doesn't make sense for your particular use case, it should be easy to alter the code below as you see fit.
Since you want the next birthday in the year rather than the closest birthday, you can use the year of date and the month and day from birth{i} to create a date for each person's next birthday. Then you can sinmply take the earliest value from each household. I reshape long, and generate a person and household id in order to do this.
Make example data
clear
set obs 6
set seed 1996
generate date = floor((mdy(12,31,2020)-mdy(12,1,2015)+1)*runiform() + mdy(12,1,2015))
format date %td
forvalue i = 1/6 {
gen birth`i' = floor((mdy(12,31,1996)-mdy(12,1,1980)+1)*runiform() + mdy(12,1,1980)) if _n < `i' == 0
format birth`i' %td
}
replace birth6 = birth4 in 6 // want a tie
replace birth2 = date("29feb1996","DMY") in 3 // Feb 29
Find Next Birthday
gen household_id = _n
reshape long birth, i(date household_id) j(person)
drop if mi(birth)
gen person_next_birthday = mdy( month(birth), day(birth), year(date))
* TREAT FEB 29 as if they have a march 1 birthday in non-leap years
replace person_next_birthday = mdy(3,1,year(date)) if month(birth) == 2 ///
& day(birth) == 29 & mod(year(date),4)!=0
replace person_next_birthday = mdy( month(birth), day(birth), year(date) + 1) if person_next_birthday < date
replace person_next_birthday = mdy(3,1,year(date)+1) if month(birth) == 2 ///
& day(birth) == 29 & mod(year(date) + 1,4)!=0 & person_next_birthday < date
format person_next_birthday %td
bysort household_id (person_next_birthday): gen next_bday = person_next_birthday[1]
format next_bday %td
drop person_next_birthday
reshape wide birth, i(date household_id next_bday) j(person)
gen next_bday_persons = ""
* Make a string to present household persons who have next bday
foreach v of varlist birth* {
local person = subinstr("`v'","birth","",.)
local condition = "month(`v') == month(next_bday) & day(`v') == day(next_bday)"
local condition_feb29 = "month(next_bday) == 3 & day(next_bday) == 1 & month(`v') == 2 & day(`v') == 29"
replace next_bday_persons = next_bday_persons + "|`person'" if `condition' | `condition_feb29'
}
replace next_bday_persons = regexr(next_bday_persons,"^\|","")
order next_bday_persons, after(next_bday)
The last loop is unnecessary, but illustrates that this is robust to ties.
I have a variable with a date table that looks like this
* table:
[day]
* number: 15
[year]
* number: 2015
[month]
* number: 2
How do I get the days between the current date and the date above? Many thanks!
You can use os.time() to convert your table to seconds and get the current time and then use os.difftime() to compute the difference. see Lua Wiki for more details.
reference = os.time{day=15, year=2015, month=2}
daysfrom = os.difftime(os.time(), reference) / (24 * 60 * 60) -- seconds in a day
wholedays = math.floor(daysfrom)
print(wholedays) -- today it prints "1"
as #barnes53 pointed out could be off by one day for a few seconds so it's not ideal, but it may be good enough for your needs.
You can use the algorithms gathered here:
chrono-Compatible Low-Level Date Algorithms
The algorithms are shown using C++, but they can be easily implemented in Lua if you like, or you can implement them in C or C++ and then just provide Lua bindings.
The basic idea using these algorithms is to compute a day number for the two dates and then just subtract them to give you the number of days.
--[[
http://howardhinnant.github.io/date_algorithms.html
Returns number of days since civil 1970-01-01. Negative values indicate
days prior to 1970-01-01.
Preconditions: y-m-d represents a date in the civil (Gregorian) calendar
m is in [1, 12]
d is in [1, last_day_of_month(y, m)]
y is "approximately" in
[numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
Exact range of validity is:
[civil_from_days(numeric_limits<Int>::min()),
civil_from_days(numeric_limits<Int>::max()-719468)]
]]
function days_from_civil(y, m, d)
if m <= 2 then
y = y - 1
m = m + 9
else
m = m - 3
end
local era = math.floor(y/400)
local yoe = y - era * 400 -- [0, 399]
local doy = math.modf((153*m + 2)/5) + d-1 -- [0, 365]
local doe = yoe * 365 + math.modf(yoe/4) - math.modf(yoe/100) + doy -- [0, 146096]
return era * 146097 + doe - 719468
end
local reference_date = {year=2001, month = 1, day = 1}
local date = os.date("*t")
local reference_days = days_from_civil(reference_date.year, reference_date.month, reference_date.day)
local days = days_from_civil(date.year, date.month, date.day)
print(string.format("Today is %d days into the 21st century.",days-reference_days))
os.time (under Windows, at least) is limited to years from 1970 and up. If, for example, you need a general solution to also find ages in days for people born before 1970, this won't work. You can use a julian date conversion and subtract between the two numbers (today and your target date).
A sample julian date function that will work for practically any date AD is given below (Lua v5.3 because of // but you could adapt to earlier versions):
local
function div(n,d)
local a, b = 1, 1
if n < 0 then a = -1 end
if d < 0 then b = -1 end
return a * b * (math.abs(n) // math.abs(d))
end
--------------------------------------------------------------------------------
-- Convert a YYMMDD date to Julian since 1/1/1900 (negative answer possible)
--------------------------------------------------------------------------------
function julian(year, month, day)
local temp
if (year < 0) or (month < 1) or (month > 12)
or (day < 1) or (day > 31) then
return
end
temp = div(month - 14, 12)
return (
day - 32075 +
div(1461 * (year + 4800 + temp), 4) +
div(367 * (month - 2 - temp * 12), 12) -
div(3 * div(year + 4900 + temp, 100), 4)
) - 2415021
end
I am trying to use asp classic to find how many working days (mon - sat) are in the month and how many are left.
any help or pointers greatly appreciated!
Here's how you can find the number of Sundays in a month without iteration. Somebody posted a JavaScript solution a few months back and I ported it to VBScript:
Function GetSundaysInMonth(intMonth, intYear)
dtmStart = DateSerial(intYear, intMonth, 1)
intDays = Day(DateAdd("m", 1, dtmStart) - 1)
GetSundaysInMonth = Int((intDays + (Weekday(dtmStart) + 5) Mod 7) / 7)
End Function
So, your total work days would just be the number of days in the month minus the number of Sundays.
Edit:
As #Lankymart pointed out in the comments, the above function gives you the number of Sundays in the month but it doesn't tell you how many are left.
Here's another version that does just that. Pass in any date and it will tell you how many Sundays are left in the month starting with that date. If you want to know how many Sundays are in a full month, just pass in the first day of the month (e.g., DateSerial(2014, 8, 1)).
Function GetSundaysRemainingInMonth(dtmStart)
intDays = Day(DateSerial(Year(dtmStart), Month(dtmStart) + 1, 1) - 1)
intDays = intDays - Day(dtmStart) + 1
GetSundaysRemainingInMonth = Int((intDays + (Weekday(dtmStart) + 5) Mod 7) / 7)
End Function
Edit 2:
#Cheran Shunmugavel was interested in some specifics about how this works. First, I just want to restate that I didn't develop this method originally. I just ported it to VBScript and tailored it to the OP's requirement (Sundays).
Imagine a February during a leap year. We have 29 days during the month. We know from the start that we have four full weeks, so each weekday will be represented at least four times. But that still leaves one addition day that's unaccounted for (29 Mod 7 = 1). How do we know if we get an extra Sunday from that one day? Well, in this case, it's pretty simple. Only if our start date is a Sunday can we count an extra Sunday for the month.
What if the month has 30 days? Then we have two extra days to account for. In that case, the start date can be a Saturday or a Sunday and we can count an extra Sunday for the month. And so it goes. So we can see that if we're X additional days within an upcoming Sunday, we can count an extra Sunday.
Let's put this in tabular form:
Addl Days Needed
Day To Count Sunday
---------- ----------------
Sunday 1
Saturday 2
Friday 3
Thursday 4
Wednesday 5
Tuesday 6
Monday 7
So what we need is a formula that we can apply to these situations so that they all result in the same value. We'll need to assign some value to each day and combine that value with the number of addition days needed for Sunday to count. Seems reasonable that if we assign an inverse value to the weekdays and add that to the number of additional days, we can get the same result.
Addl Days Needed Value Assigned
Day To Count Sunday To Weekday Sum
---------- ---------------- -------------- ---
Sunday 1 6 7
Saturday 2 5 7
Friday 3 4 7
Thursday 4 3 7
Wednesday 5 2 7
Tuesday 6 1 7
Monday 7 0 7
So, if weekday_value + addl_days = 7 then we count an extra Sunday. (We'll divide this by 7 later to give us 1 additional Sunday). But how do we assign the values we want to the weekdays? Well, VBScript's Weekday() function already does this but, unfortunately, it doesn't use the values we need by default (it uses 1 for Sunday through 7 for Saturday). We could change the way Weekday() works by using the second param, or we could just use a Mod(). This is where the + 5 Mod 7 comes in. If we take the Weekday() value and add 5, then mod that by 7, we get the values we need.
Day Weekday() +5 Mod 7
---------- --------- -- -----
Sunday 1 6 6
Saturday 7 12 5
Friday 6 11 4
Thursday 5 10 3
Wednesday 4 9 2
Tuesday 3 8 1
Monday 2 7 0
That's how the + 5 Mod 7 was determined. And, with that solved, the rest is easy(er)!
#Zam is on the right track you need to use WeekDay() function, here is a basic idea of how to script it;
<%
Dim month_start, month_end, currentdate, dayofmonth
Dim num_weekdays, num_past, num_future
Dim msg
'This can be configured how you like even use Date().
month_start = CDate("01/08/2014")
month_end = DateAdd("d", -1, DateAdd("m", 1, month_start))
msgbox(Day(month_end))
For dayofmonth = 1 To Day(month_end)
currentdate = CDate(DateAdd("d", dayofmonth, month_start))
'Only ignore Sundays
If WeekDay(currentdate) <> vbSunday Then
num_weekdays = num_weekdays + 1
If currentdate <= Date() Then
num_past = num_past + 1
Else
num_future = num_future + 1
End If
End If
Next
msg = ""
msg = msg & "Start: " & month_start & "<br />"
msg = msg & "End: " & month_end & "<br />"
msg = msg & "Number of Weekdays: " & num_weekdays & "<br />"
msg = msg & "Weekdays Past: " & num_past & "<br />"
msg = msg & "Weekdays Future: " & num_future & "<br />"
Response.Write msg
%>
How about using "The Weekday function returns a number between 1 and 7, that represents the day of the week." ?
How can I get the Today -2 days (the last 2 working days from now)? but skipping the weekend?
Example #1: Today is February 25, I want February 21
Example #2: Today is February 26, I want February 24
PS: Date format is DD/MM/YYYY
I have this, but the result is going forward, should I use datediff or what?:
<%
Dim d
d = DateAdd("m", 1, Now)
d = "01/" & Month(d) & "/" & Year(d)
d = DateAdd("d", -1, d)
If Weekday(d) = 7 Then
d = DateAdd("d", -1, d)
ElseIf Weekday(d) = 1 Then
d = DateAdd("d", -2, d)
End If
Response.Write "Day: " & d
%>
To get your desired result you need to subtract 3 days on Saturdays, 4 days on Sundays and Mondays, and 2 days on all other days. This can be achieved with something like this:
today = Now
num = Weekday(today, vbWednesday)
d = today - (2 + num\5 + num\6)
response.write "Two working days back: " & d
The Weekday function returns a numeric value for each weekday. By basing the week on Wednesday you can calculate the additional number of days you need to subtract from the current date with integer divisions:
num\5 returns 1 for Saturday, Sunday and Monday, and 0 otherwise.
num\6 returns 1 for Sunday and Monday, and 0 otherwise.
Thus the term 2 + num\5 + num\6 becomes 3 for Saturdays, 4 for Sundays and Mondays, and 2 for all other days.
This might be overkill for what you need but here are two routines I use in my scripts to add or subtract workdays while considering weekends and holidays.
Function AddWorkingDays(dtStart, intDays)
' Start/Default case...
AddWorkingDays = CDate(dtStart)
' If positive days, step forward, otherwise step backward...
Dim intStep, intCount
If intDays > 0 Then intStep = 1 Else intStep = -1
Do While intCount <> intDays
AddWorkingDays = AddWorkingDays + intStep
If IsValidDate(AddWorkingDays) Then intCount = intCount + intStep
Loop
End Function
Function IsValidDate(d)
Dim intWeekday, intMonth, intDay
intWeekday = Weekday(d)
intMonth = Month(d)
intDay = Day(d)
' Weekend dates are not acceptable...
If intWeekday = vbSaturday Or intWeekday = vbSunday Then Exit Function
' Holidays are also not acceptable...
If intMonth = 01 Then If intDay = 01 Then Exit Function ' New Year's Day
If intMonth = 07 Then If intDay = 04 Then Exit Function ' Independence Day
If intMonth = 12 Then If intDay = 25 Then Exit Function ' Christmas Day
' Memorial Day is the last Monday in May...
If intWeekday = vbMonday Then If intMonth = 05 Then If intDay >= 25 Then Exit Function
' ... (Thanksgiving, others) ...
' All tests passed. Date is a valid workday...
IsValidDate = True
End Function
Is there a built in function that will tell me which days are work days? this is what i mean,
If I were to choose today's date (6/14/2011), it will give me any inspection numbers clocked out today. This lead time includes weekends. So if I had a customer start a project on the 10th (Friday) and finish it today; it would show it took about five days, instead of three.
I believe there used to be a function to do this a long long time ago, but I believe that function has since been removed. I believe that you should be able to use something like the following which calculates the business days between two dates:
DateDiff ("d", {Orders.OrderDate}, {Orders.ShipDate}) -
DateDiff ("ww", {Orders.OrderDate}, {Orders.ShipDate}, crSaturday) -
DateDiff ("ww", {Orders.OrderDate}, {Orders.ShipDate}, crSunday)
This gets the total days difference and subtracts the saturdays and sundays from the total. Note this does not include holidays. For that you'd need to maintain them in your own User Function Library and include them in the calculation.
Hope this helps.
This is the solution i came up with. Pretty much if it is anything over 7 days i know how many days to subtract. if it is under 7 days i can still figure out if it spanned the weekend. Crystal reports has a function DayOfWeek that returns a number for the day i.e. Sunday = 1, Monday = 2, etc. If the finish time day number is less than the start time number we know it passed the weekend. and we can subtract 2.
timeDiff is startdate - finishdate.
if({#timeDiff} >= 35) then
{#timeDiff} - 10
else if({#timeDiff} >= 28) then
{#timeDiff} - 8
else if({#timeDiff} >= 21) then
{#timeDiff} - 6
else if({#timeDiff} >= 14) then
{#timeDiff} - 4
else if({#timeDiff} >= 7) then
{#timeDiff} - 2
else if(DayOfWeek({Command.Finishdate}) < DayOfWeek({Command.Startdate})) then
{#timeDiff} - 2
else
{#timeDiff}
I have a more in depth explanation on my website. the link is here
Here is a monster solution that also takes public holidays into account:
// WorkingDays
// Count the number of working days between a start and an end date.
//
// startDate - first date in the interval
// endDate - last date in the interval
// countStartAndEnd - if true 1 feb to 2 feb will count as 2 days
// if false 1 feb to 2 feb will count as 1 day
// given both of them are working days
Function (dateVar startDate, dateVar endDate, optional booleanVar countStartAndEnd := False)
local NumberVar Weeks;
local NumberVar Days;
local NumberVar Hol;
// 5 days for every week (whole or partial)
Weeks := (Truncate (endDate - dayofWeek(endDate) + 1 - (startDate - dayofWeek (startDate) + 1)) /7 ) * 5;
// Number of days in partial weeks (can be positive or negative)
Days := DayOfWeek(endDate) - DayOfWeek(startDate) + 1 +
(if DayOfWeek(startDate) = crSunday then -1 else 0) +
(if DayOfWeek(endDate) = crSaturday then -1 else 0);
// Count number of public holidays in the period
local NumberVar iYear;
local NumberVar i;
for iYear := Year(startDate) to Year(endDate) do (
Local DateVar Array Holidays := getHolidays(iYear);
for i := 1 to uBound(Holidays) do (
local NumberVar hMonth := Month(Holidays[i]);
local NumberVar hDay := Day(Holidays[i]);
local DateVar hDate := cDate(iYear, hMonth, hDay);
if DayOfWeek(hDate) in crMonday to crFriday and
hDate in startDate to endDate then Hol := Hol+1;
);
);
// Return number of working days
Weeks + Days - Hol - toNumber(not countStartAndEnd);
Code above modified from solution found at KenHamady.
The following function is called by the previous function and returns all public holidays:
// getHolidays
// Returns an array with all public holidays for a given year
// These are Swedish holidays. Modify as needed.
Function (Numbervar yyyy)
Datevar Array holidays;
local Datevar holiday;
local Datevar easterSunday := getEasterSunday(yyyy);
// New Years Day
// 1 jan
holiday:=Date(yyyy, 1, 1);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Epiphany
// 6 jan
holiday:=Date(yyyy, 1, 6);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Good Friday
// 2 days before easter sunday
holiday:=cDate(DateAdd("d", -2, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Holy Saturday
// 1 day before easter sunday
holiday:=cDate(DateAdd("d", -1, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Easter Sunday
// The first Sunday following the first ecclesiastical full moon that occurs on or after the day of the vernal equinox
holiday:=cDate(DateAdd("d", -2, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Easter Monday
// 1 day after easter sunday
holiday:=cDate(DateAdd("d", 1, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Labour day
// 1 may
holiday:=Date(yyyy, 5, 1);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Ascension
// 39 days after easter sunday
holiday:=cDate(DateAdd("d", 39, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// National day
// 6 june
holiday:=Date(yyyy, 6, 6);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Midsummer's eve
// The friday in the interval 19 june - 25 june
holiday:=cDate(DateAdd("d", 1-dayOfWeek(Date(yyyy, 6, 25), crFriday), Date(yyyy, 6, 25)));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// All saints' day
// The saturday in the interval 31 october - 6 november
holiday:=cDate(DateAdd("d", 1-dayOfWeek(Date(yyyy, 11, 6), crSaturday), Date(yyyy, 11, 6)));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Christmas eve
// 24 december
holiday:=Date(yyyy, 12, 24);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Chritmas day
// 25 december
holiday:=Date(yyyy, 12, 25);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// St. Stephen's Day
// 26 december
holiday:=Date(yyyy, 12, 26);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// New year's eve
// 31 december
holiday:=Date(yyyy, 12, 31);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
holidays;
Code above based on the custom function in this post by craig.
The holiday function need to be able to get the date for easter sunday for a given year:
// getEasterSunday
// Returnes a dateVar of the easter sunday for a given year
//
// Based upon formula from http://aa.usno.navy.mil/faq/docs/easter.php
Function (numberVar yyyy)
local numberVar c := int(yyyy / 100);
local numberVar n := yyyy - 19 * int(yyyy / 19);
local numberVar k := int((c-17)/25);
local numberVar i := c - int(c/4) - int((c-k)/3) + 19*n + 15;
i := i - 30 * int(i/30);
i := i - int(i/28) * ( 1 - int(i/28) * int(29/(i+1)) * int((21-n)/11));
local numberVar j := yyyy + int(yyyy/4) + i + 2 - c + int(c/4);
j := j - 7 * int(j/7);
local numberVar l := i - j;
local numberVar m := 3 + int((l+40)/44);
local numberVar d := l + 28 - 31 * int(m/4);
cDate(yyyy, m , d);
Easter sunday calculation formula from United States Naval Observatory.