## PICAXE Clock Exercise: Day of Week

The day of the week is the one item in the clock that can be calculated from the date, month, and year. The DS1307 provides a day of week index that increments at midnight and rolls over from 7 to 1. The datasheet indicates that it is up to the clock user to figure out how he wants to use it.

Since the day of week is a dependent value, this clock exercise calculates it and uses the clock chip data register simply as storage for an offset into a day of week abbreviation table. That means a bit of care needs to be taken so the midnight clock increment doesn’t confuse things.

The Tomohiko Sakamoto algorithm is used here. It is often seen in C as:

```{ static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; }
```

To simplify this and convert to PICAXE, require the date to be a 2 digit year in the 21st century (like the clock chip keeps) and simplify:

```y+2k + y/4+2k/4 - y/100-2k/100 + y/400+2k/400 ...
y + y/4 - y/100 + y/400 + 2k + 500 - 20 + 5 ...
y + y/4 -   0   +   0   + 2485 ...
```

The zero values are due to integer arithmetic where 2 digit year divided by 100 or more is zero as any fraction rounds down (is truncated).

In the PICAXE subroutine, the inputs are byte registers labeled i, j, and k for year, month, and date. A byte value labeled wd is returned with a range from 0 to 6 where 0 is Sunday. i and j are destroyed in the calculation. A word variable, ij, is used and can be the composit of the i and j byte registers.

Note that the clock chip reports in BCD so the calling routine needs to convert clock data to binary numbers.

```calculate_dow:
; SerTxd ("Find DOW for ",#i,"/",#j,"/",#k,cr,lf)
If j < 3 then   ; jan or feb
dec i       ; decrement yr
EndIf
dec j           ; decrement month for lookup index
lookup j, (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4), b0
j = i/4
j = j + i + b0 + k
ij = j + 2485
ij = ij % 7     ; 0 is Sunday
wd = ij
; put clock_data_dow, wd      ; stash in scratchpad as a read value
Return
```

The day of week is used to put a day of week abreviation on the display and to calculate daylight savings time adjustments. To test the calculation, I created a spreadsheet with intermediate values to make a table of dates with day of week. I could then compare the results with a calendar and the intermediate values with the PICAXE calculation to see if it came up with the correct values.