If you shop at Amazon anyway, consider using this
link. We receive a few cents from each purchase. Thanks.
If you benefit from the website, in terms of
knowledge, entertainment value, or something otherwise useful,
consider making a donation via PayPal to help defray the
costs. (No PayPal account necessary to donate via credit
card.) Transaction is secure.
Send an e-mail with your
comments about this program (or anything else).
This program investigates how Daylight Saving Time start and end dates
can be calculated using simple equations without resorting to high level
Background & Techniques
Daylight Saving Time is not one of mankind's greatest inventions, but it does
provide an excuse to study the
mathematics of associating day of the week with the day of the month.
Delphi and most other high level languages incorporate date-time procedures to
simplify the calculation, but
there are thousands of devices with embedded processors which may not have this
option but still need to
accurately track the current local time. I recently researched the issue for a
manufacturer of such a device who
had found formulas but wanted to understand what was behind the "magic" so they
can adapt to various
localized DST definitions or future definition changes.
Most of the world (Asia, Africa, and South America except Brazil) avoid DST
altogether by not defining it. USA
(except for Arizona) and the Euro zone have formal definitions. The current USA
definition took effect in 2007
and the European definition in 1998. The definitions below include equations
http://www.webexhibits.org/daylightsaving/i.html which also includes
attributions for the developers of the
|USA prior to 2007 began DST on the 1st Sunday in April (Day of month
= 1 + (2+6*Y-Y/4) mod 7) and ended it on the last Sunday of October (Day
of month = 31- (1+5*Y/4+1) mod 7).|
|USA starting in 2007, extended DST to begin on the 2nd Sunday in March (Day
of month = 14 - (1+Y*5/4) |
mod 7) and end on the 1st Sunday in November (Day of month = 7 - (1 +
5*Y/4) mod 7).
|For Europe, DST begins on the last Sunday in March (Day of month = 31
- (4+ 5*Y/4 ) mod 7) and ends on the last Sunday in October (Day of
month = 31 - (1 + 5*Y/4) mod 7).|
Notice that we have six equations with the last five being very similar in
structure. Y in the equations is the 4 digit year. For consistency,
I have rearranged the terms from the way they appear on the
webexhibits site. All of the "/4" operations represent Integer
division, i.e. any fractions are dropped so the term is always a whole
number. "Mod 7" terms are modulus operations which return the
remainder (0 to 6) when the first operand is divided by 7. That explains
the initial 1+ in the first equation since we need a number from 1 to 7 for the
day of month for the first Sunday. The other five equations have initial
terms of 7-, 14-, or 31- representing the 1st, 2nd, or last Sunday
of a month so their Mod 7 term must return the number of days from that latest
date back to a Sunday.
If we look at the Mod 7 terms, notice that the 6Y-y/4 in Equation 1
says that we are going to add 6 days for every year, except we'll subtract
one day for each leap year. On first look this seems counterintuitive
since a normal year is 52 weeks + 1 day. But it makes sense if you
think in terms of what happens to a particular day of the week from year to
year. It's true that the date moves forward by one day per year, but that
also means that the day of week moves backward one day or forward 6 days,
whichever is more convenient per year.
In the strange world of modulo
arithmetic, it turns out that (-Y mod 7) is the equivalent to (6Y mod 7) so we
could replace 6Y with -Y and (6Y-Y/4) with (-Y-Y/4
= -5Y/4), the same term
that appears in the other five equations. The only problem is that whatever day
that represents might apply to any 7 day increment before or after that date.
Enter the "magic" number added to -5Y/4 that makes the equation apply to a
Sunday. These are already provided by the authors for the five
equations, but let us find one for the 1st equation if we want to put it into
our new "standard" form. For the 1st Sunday in April we'll one known value
and solve Day of Month = 7 - (X + 5Y/4) mod 7 for X.
Any year should do so we'll try 2012 where April 1 is a Sunday so we need to
= 7 - (X + 5*2012 / 4) mod 7
Rearranging: (X+ 5 * 2012 / 4) mod 7 = 7 - 1 = 6
operator is distributive, so X mod 7 + 2515 mod 7 = 6
7 + 2 = 6 ==> X mod 7 = 4 ==> X =
So our revised equation for the first Sunday in April is: Day
of Month = 7 - (4 + 5Y/4) mod 7. Checking for 2006 and 2013 we get 4
and 7; both correct so 4 seems to be the correct "magic" number
Note that none of the equations take into account 100 year and 400 year Leap Year
exception rules so they only provide
valid results from 1900 through 2099. That range is probably sufficient
for DST calculations.
The program implements these equations and also a version using the high level
date-time routines of Delphi.
The results are compared so that for a range of input years you can display all
results or only the "errors"
(useful for debugging). Results agree within the 1900 - 2099 date range
Running/Exploring the Program
Suggestions for Further Explorations
||Adding the 100 and 400 year exceptions would
allow more generalized calculations for any given occurrence of any
day of week in any month and year.
|Original: April 20,2012
April 21, 2012