Dates Of Moving Holidays

This section handles the problem of computing the dates of moving holidays and is based on perpetual calendar Algorithm 9.

See Internal Ref:
Nth DoW of Year / Month

According to a federal law (The Uniform Monday Holiday Act, Public Law 90-363) that took effect on January 1st, 1971, certain federal holidays would henceforth always be celebrated on a Monday.

These holidays move in the sense that, due to the way our calendar system works, for any holiday to consistently fall on a Monday, it necessarily has to fall on a different day of the month each year.  This applies to any holiday that alway falls on a fixed weekday every year.  Conversely, any holiday that has a consistent calendar date, like Christmas Day (Dec 25th), the day of the week on which it falls must change each year.

To compute the (`N`)th `Dow` of month (`m`) of year (`y`), requires `5` arguments:
• `N` = `1`, `2`, `3`, `...`

• `DoW` = Day of Week index code (`0` to `6`)
Where:   `0`=Sun, `1`=Mon, `2`=Tue, `3`=Wed, `4`=Thu, `5`=Fri and `6`=Sat

• `y` = Year value (from `1971`, when used for federal holidays)

• `m` = Month (`1` to `12`)

• `CalMode` (`0`=Julian  or  `1`=Gregorian)

Given the above arguments, and calling Algorithm 1 and Algorithm 2, the following pseudocode algorithm computes the ISO integer-encoded date (`ISOymd`) value.

Algorithm 9:

Given (`N`, `Dow`, `y`, `m`, `Calmode`), compute the corrersponding ISO integer-encoded date (`ISOymd`) of the (`N`)th `DoW` in month (`m`) of year (`y`)
.

```
if (y < 0) then YearSign = -1 else YearSign = 1

ISOymd1 = YearSign*(10000*abs(y) + 100*m + 1)
JD1 = JD_For_ISOymd (ISOymd1, CalMode)
DoW1 = (JD1 + 1) mod 7
dDoW = DoW - DoW1

if (dDoW < 0) then u = dDoW + 7 else u = dDoW

JD = JD1 + u + 7*(N-1)

ISOymd = ISOymd_For_JD (JD, CalMode)

```

EXAMPLE 1:

Find George Washington's birthday in 2010 (`y=2010`), always the 3rd (`N=3`) Monday (`DoW=1`) in February (`m=2`) and always on the Gregorian (`CalMode=1`) calendar.
```
N = 3
DoW = 1
y = 2010
m = 2
CalMode = 1 (Gregorian)

if (y < 0) then YearSign = -1 else YearSign = 1
YearSign = 1

ISOymd1 = YearSign*(10000*abs(y) + 100*m + 1)
= 1*(20100000 + 200 + 1)
= 20100201

JD1 = JD_For_ISOymd (20100201, 1) = 2455229

DoW1 = (JD1 + 1) mod 7 = 2455230 mod 7 = 1 (Monday)

dDoW = DoW - DoW1 = 1 - 1 = 0
if (dDoW < 0) then u = dDoW + 7 else  u = dDoW
u = 0

JD = JD1 + u + 7*(N-1)
= 2455229 + 0 + 14
= 2455243

ISOymd = ISOymd_For_JD (2455243, 1) = 20100215 = 2010 Feb 15th

```
So, George Washington's birthday in 2010 was observed on Monday, February 15th.

 G 2010      February Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

EXAMPLE 2:

Find Thanksgiving Day, 2010 (y=2010) - Always the 4th (N=4) Thursday (DoW=4) in November (m=11)
```
N = 4
DoW = 4
y = 2010
m = 11
CalMode = 1 (Gregorian)

if (y < 0) then YearSign = -1 else YearSign = 1
YearSign = 1

ISOymd1 = YearSign*(10000*abs(y) + 100*m + 1)
= 1*(20100000 + 1100 + 1)
= 20101101

JD1 = JD_For_ISOymd (20101101, 1) = 2455502

DoW1 = (JD1 + 1) mod 7 = 2455503 mod 7
= 1 (Monday)

dDoW = DoW - DoW1 = 4 - 1 = 3
if (dDoW < 0) then u = dDoW + 7 else u = dDoW
u = 3

JD = JD1 + u + 7*(N-1)
= 2455502 + 3 + 21
= 2455526

ISOymd = ISOymd_For_JD (2455526, 1) = 20101125 = November 25th, 2010

```
So, Thanksgiving Day, 2010, always the 4th Thursday in November, was November 25th.

 G 2010      November Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

© PHP Science Labs - 2017