I'm currently exploring different integrations that can be done between Google App Script and Git. This is part of a bigger attempt to integrate Git data into my project management system. I'll post more on that later. GitHub supports a number of very nice sub-systems. One of them is the GitHub Issues ticket tracking system. It's fairly robust and comes with GitHub - which means it's highly integrated out-of-the-box. Integration with Google's App Script is done via the fetchURL command and JSON object manipulation. After a good bit of experimentation, I've settled on querying GitHub Issues with an "on open spreadsheet event" to avoid issues with Google's quota system. Essentially, Google prevents you from calling the fetchURL command more than X times (see the quota limits ) per day. That's not great if you have people actively working and changing data in a spreadsheet. Some of my other App Script routines are running thousands of times per d
Anyone else out there ever run into the need for a simple little list of holidays? I do a fair amount of stuff that involves questions like "Are we off on such and such a day?" where you have to figure out, "When is Easter this year anyway?" That's pretty easy if you look it up on a calendar. Now try doing that in code.
At any rate, I wrote a tiny little class to provide some basic holidays out. Help yourself to the code, it's not complicated, just annoying. The biggest trick is finding the information in the first place. This is US-oriented, but I'd be glad to extended it if someone wants some other days in there. It would be helpful if you could provide the holiday information you're interested in though (i.e., My Personal Holiday is the 3rd Tuesday of May or whatever). Oh, one last caveat. If the date doesn't appear (like Inauguration day), the DateTime will be a 0. That's fine for comparisons, but if you just do a dump of the dates, it gives you 1899.
At any rate, I wrote a tiny little class to provide some basic holidays out. Help yourself to the code, it's not complicated, just annoying. The biggest trick is finding the information in the first place. This is US-oriented, but I'd be glad to extended it if someone wants some other days in there. It would be helpful if you could provide the holiday information you're interested in though (i.e., My Personal Holiday is the 3rd Tuesday of May or whatever). Oh, one last caveat. If the date doesn't appear (like Inauguration day), the DateTime will be a 0. That's fine for comparisons, but if you just do a dump of the dates, it gives you 1899.
unit holidayDateTime;
interface
uses sysutils;
type
THolidayClass = class
public
YearIs : word;
NewYears : TDateTime;
MLKJr : TDateTime;
Inauguration : TDateTime;
Washington : TDateTime;
ArmedForces : TDateTime;
Memorial : TDateTime;
FlagDay : TDateTime;
Independence : TDateTime;
Labor : TDateTime;
Columbus : TDateTime;
Veterans : TDateTime;
Thanksgiving : TDateTime;
Christmas : TDateTime;
Secretaries : TDateTime;
AprilFools : TDateTime;
Earth : TDateTime;
Fathers : TDateTime;
Groundhog : TDateTime;
Halloween : TDateTime;
Lincoln : TDateTime;
Mothers : TDateTime;
StPatty : TDateTime;
UnitedNations: TDateTime;
Valentines : TDateTime;
Election : TDateTime;
Flag : TDateTime;
Easter : TDateTime;
constructor Create(aYear:word);
procedure changeYear(aYear:word);
function getEaster:TDateTime;
class procedure SafeMonth(var month, y:word);
class function getDOW(year, month, dow, weekNum:word):TDateTime;
class function getLastDOW(year, month, dow:word):TDateTime;
end;
implementation
class procedure THolidayClass.SafeMonth(var month, y:word);
begin
while month>12 do
begin
dec(month,12);
inc(y);
end;
end;
class function THolidayClass.getDOW(year, month, dow, weekNum:word):TDateTime;
var i:word;
begin
result:=EncodeDate(year, month, 1);
for i:=0 to 7 do
if DayOfWeek(result+i)=dow then
begin
result:=result+i;
result:=result+((weeknum-1)*7); //move to the correct week, 1st week is inc of 0
break;
end;
end;
class function THolidayClass.getLastdow(year, month, dow:word):TDateTime;
var i:word;
begin
//Year has to be on the stack, SafeMonth could change year
inc(month);
SafeMonth(month,year);
result:=EncodeDate(year,month,1)-1;
for i:=0 to 7 do
if DayOfWeek(result-i)=dow then
begin
result:=result-i;
break;
end;
end;
constructor THolidayClass.Create(aYear:word);
begin
ChangeYear(aYear);
end;
function THolidayClass.getEaster:TDateTime;
var a,b,c,d,e,f,g,h,i,k,l,m,p : integer;
Easter_Month, Easter_Day : integer;
begin
a:=yearis mod 19;
b:=yearis div 100;
c:=yearis mod 100;
d:=b div 4;
e:=b mod 4;
f:=(b+8) div 25;
g:=(b-f+1) div 3;
h:=(19*a+b-d-g+15) mod 30;
i:=c div 4;
k:=c mod 4;
l:=(32+2*e+2*i-h-k) mod 7;
m:=(a+11*h+22*l) div 451;
Easter_Month :=(h+l-7*m+114) div 31; //[3=March, 4=April]
p:=(h+l-7*m+114) mod 31;
Easter_Day:=p+1; //(day in Easter Month)
result:=EncodeDate(YearIs,Easter_Month,Easter_Day);
end;
procedure THolidayClass.ChangeYear(aYear:word);
const
DayOfWeek_Sunday = 1;
DayOfWeek_Monday = 2;
DayOfWeek_Tuesday = 3;
DayOfWeek_Wednesday = 4;
DayOfWeek_Thursday = 5;
DayOfWeek_Friday = 6;
DayOfWeek_Saturday = 7;
begin
YearIs := aYear;
Easter := getEaster;
NewYears := EncodeDate(YearIs,1,1);
MLKJr := getdow(YearIs, 1, DayOfWeek_Monday, 3);
if (YearIs - 1937) mod 4 = 0 then
Inauguration := EncodeDate(YearIs, 1, 20)
else
Inauguration := 0;
Election := 0;
Flag := EncodeDate(YearIs,6,14);
Washington := getdow(YearIs, 2, DayOfWeek_Monday, 3);
ArmedForces := getdow(YearIs, 5, DayOfWeek_Saturday, 3);
Memorial := getLastdow(YearIs, 5, DayOfWeek_Monday);
FlagDay := EncodeDate(YearIs,6,14);
Independence := EncodeDate(YearIs,7,4);
Labor := getdow(YearIs, 9, DayOfWeek_Monday,1);
Columbus := getdow(YearIs, 10, DayOfWeek_Monday,2);
Veterans := EncodeDate(YearIs,11,11);
Thanksgiving := getdow(YearIs, 11, DayOfWeek_Thursday,4);
Christmas := EncodeDate(YearIs,12,25);
Secretaries := getLastdow(YearIs, 5, DayOfWeek_Saturday) - 3; //wednesday before last saturday in april
AprilFools := EncodeDate(YearIs,4,1);
Earth := EncodeDate(YearIs,4,22);
Fathers := getdow(YearIs, 6, DayOfWeek_Sunday,3);
Groundhog := EncodeDate(YearIs,2,2);
Halloween := EncodeDate(YearIs,10,31);
Lincoln := EncodeDate(YearIs,2,12);
Mothers := getdow(YearIs, 5, DayOfWeek_Sunday,2);
StPatty := EncodeDate(YearIs,3,17);
UnitedNations:= EncodeDate(YearIs,10,24);
Valentines := EncodeDate(YearIs,2,14);
end;
end.
Comments
please refer to these sources of info
http://www.smart.net/~mmontes/freq3.html#LBY
2001 4/15
2002 3/31
2003 4/20
2004 4/11
2005 3/27
2006 4/16
2007 4/8
2008 3/23
2009 4/12
2010 4/4
and wikipedia
http://en.wikipedia.org/wiki/Easter
or the following code from about.com which seems to calculate it correctly
http://delphi.about.com/cs/adptips2002/a/bltip0302_2.htm
Frank
The Easter code is a direct translation of Samuel Butcher's Easter algorithm from 1876. I think the original I took was from Peter Duffett-Smith's Practical Astronomy With Your Calculator, but I'm not 100% sure. As I mentioned, I've misplaced the source for some of these calculations. At any rate, I used the following code:
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
THC:THolidayClass;
begin
THC:=THolidayClass.Create(2000);
for i := 2000 to 2024 do
begin
THC.changeYear(i);
ListBox1.Items.add(FormatDateTime('m/d/y', THC.Easter));
end;
THC.Free;
end;
to test it and derived the same dates as your references.
Also, I've updated the post slight to fix the typos in my Easter add-on. One of the hazards of adding code directly into the HTML and formatting it instead of copying it from the source file.
I looked at Zarko's post and wasn't able to determine which algorithm he was using but it appears to generate the same dates as mine.
Could you provide a few sample dates that don't match or did I misinterpret what you were saying?
m