Exact match. Not showing close matches.
PICList
Thread
'[PIC] Leap Year Code good for 400 Years?'
2006\07\26@213005
by
Brooke Clarke

Hi:
I've recently discovered that the code in Microchip TB028 (and the
hardware real time clocks that are commonly being sold) only use the 4
year test for leap year. This will work OK till midnight Feb 28 2100.
Although I'll be long gone by then it would be nice if a clock could be
used to determine the day of the week for past and future dates so I'm
looking for a routine that will determine if a year is a leap year and
that works from 1582 to 9999+.
A strategy might be to first do a couple of rotate right file operations
on a 16 bit unsigned integer holding the year in a couple of bytes,
checking for a carry on each rotate. A carry means not a leap year and
stop any further calculation.
Then a loop that starts with the shifted year (i.e.. starts with year/4)
and then subtract 25 repeatedly (i.e. subtracting 100 from the unshifted
year).
If the loop terminates with a carry out it's a leap year (i.e. could
only divide by 4).
If the loop terminates with a zero remainder the year is divisible by
100 so might be a leap year, depending . . .
If the loop counter rotated right twice generates no carries the year is
divisible by 400 and is a leap year else it is not a leap year.
I've worked on this all day and am still don't see light at the end of
the tunnel. I find that status,C is not changed by dec or incf. That
the meaning of status,C changes depending on what the prior operation
was. So was hoping that someone has already figured out how to do it?
PS  The LCD hardware commands for cursor and blink on/off are global in
nature and so can not be on when the LCD is being updated since they
would be applied to all the characters getting updated. That means they
are not usable for clock displays. But software blinking, like in
AN582, does work nicely.
Have Fun,
Brooke

w/Java http://www.PRC68.com
w/o Java www.pacificsites.com/~brooke/PRC68COM.shtml
http://www.precisionclock.com
2006\07\26@214803
by
Jinx
> A strategy might be to....
... use a table ?
2006\07\26@232941
by
Rolf
2006\07\27@041525
by
Tamas Rudnai
Are you considering to produce something that you expect to be still used in
2100? Most of the devices has 13 years lifetime, couple may reach 1015...
but I might missed the point :)
Tamas
On 27/07/06, Rolf <spam_OUTlearrTakeThisOuTrogers.com> wrote:
{Quote hidden}
> 
2006\07\27@043149
by
Russell McMahon
To involve more people it may be useful to spell out the total
applicable rule set you are trying to work to.
Is it:
/4 = leap year
except /100 not a leap year
except /400 is a leap year
[except /1000 ... ]?
Or ??
RM
{Quote hidden}> I've recently discovered that the code in Microchip TB028 (and the
> hardware real time clocks that are commonly being sold) only use the
> 4
> year test for leap year. This will work OK till midnight Feb 28
> 2100.
> Although I'll be long gone by then it would be nice if a clock could
> be
> used to determine the day of the week for past and future dates so
> I'm
> looking for a routine that will determine if a year is a leap year
> and
> that works from 1582 to 9999+.
2006\07\27@043215
by
Russell McMahon
2006\07\27@052039
by
Jinx
> /4 = leap year
> except /100 not a leap year
> except /400 is a leap year
> [except /1000 ... ]?
http://en.wikipedia.org/wiki/Leap_year
"The accumulated difference between the Gregorian calendar and
the vernal equinoctial year amounts to 1 day in about 8,000 years.
This suggests that the calendar needs to be improved by another
refinement to the leap year rule: perhaps by avoiding leap years in
years divisible by 8,000"
2006\07\27@052325
by
D. Jay Newman
I seem to remember:
/4 : leap year
/20 : not a leap year
/100 : is
{Quote hidden}> To involve more people it may be useful to spell out the total
> applicable rule set you are trying to work to.
>
> Is it:
>
> /4 = leap year
> except /100 not a leap year
> except /400 is a leap year
> [except /1000 ... ]?
>
> Or ??
>
>
> RM
>
> > I've recently discovered that the code in Microchip TB028 (and the
> > hardware real time clocks that are commonly being sold) only use the
> > 4
> > year test for leap year. This will work OK till midnight Feb 28
> > 2100.
> > Although I'll be long gone by then it would be nice if a clock could
> > be
> > used to determine the day of the week for past and future dates so
> > I'm
> > looking for a routine that will determine if a year is a leap year
> > and
> > that works from 1582 to 9999+.
>
> 
2006\07\27@060147
by
Tony Smith

> Subject: Re: [PIC] Leap Year Code good for 400 Years?
>
> I seem to remember:
>
> /4 : leap year
> /20 : not a leap year
> /100 : is
>
Hmm, /20, that's a new one. Hooray for leap year confusion, I might need a
job in 2100, or even sooner!
I got:
/4 : Leap year
/100 : Not a leap year
/400 : Leap year
The /400 gets forgotten a lot, so people thought 2000 wasn't a leap year
when it was. Of course, all the /4 is enough people got it right too.
Date code is wonderful stuff.
MS Excel has a leap year bug, but that's because Lotus got it wrong first.
Can't break all those 123 spreadsheets.
A company I once worked for developed programs in 1980, so to save space on
those 5 1/4 floppies they only stored the date as a single digit, so 5 meant
1985. Come 1989, and a Y19.9K bug is noticed. Fixed it by allowing for 2
digits, like the rest of the world. Beside, this stuff can't last another
10 years, can it?
1999 rolls around... and it will now fall over in 2027...
I was a Y2K programmer with prior experience. Odd.
Tony
2006\07\27@060733
by
Howard Winter
Russell,
On Thu, 27 Jul 2006 20:26:59 +1200, Russell McMahon wrote:
{Quote hidden}> To involve more people it may be useful to spell out the total
> applicable rule set you are trying to work to.
>
> Is it:
>
> /4 = leap year
> except /100 not a leap year
> except /400 is a leap year
> [except /1000 ... ]?
>
> Or ??
Or you could work it out from first principles, if you know the exact (mean) length of a Solar Year.
If it was 365.25 it would just be every 4 years.
365.24 brings in the 100year exception (subtract 1/100 from the above)
365.2425 adds the 400year part (add 1/400)
and so on.
Googling the exact length of a Solar Year is left as an exercise for the reader! ;)
Cheers,
Howard Winter
St.Albans, England
2006\07\27@061123
by
Howard Winter
Jinx,
On Thu, 27 Jul 2006 21:20:33 +1200, Jinx wrote:
{Quote hidden}>
> > /4 = leap year
> > except /100 not a leap year
> > except /400 is a leap year
> > [except /1000 ... ]?
>
>
http://en.wikipedia.org/wiki/Leap_year
>
> "The accumulated difference between the Gregorian calendar and
> the vernal equinoctial year amounts to 1 day in about 8,000 years.
> This suggests that the calendar needs to be improved by another
> refinement to the leap year rule: perhaps by avoiding leap years in
> years divisible by 8,000"
OK, but I think the costbenefit doesn't justify the development time. The next time it happens just send me an email and I'll change my
clocks by hand :)
Cheers,
Howard Winter
St.Albans, England
2006\07\27@062222
by
Howard Winter
Tony,
On Thu, 27 Jul 2006 20:01:39 +1000, Tony Smith wrote:
>...
> I was a Y2K programmer with prior experience. Odd.
Me too! (ForwardY2K programmer, and Odd :)
In the late 80's I was developing a system that calculated forward dates 10 years ahead (it was a shareoption scheme and had to work out
when the options lapsed). I could see that it was getting close to needing to store 2000 and beyond, so I made sure the full 4 digits
were always there (in all dates, not just the lapse date). I knew that most programmers only stored the last two year digits, and I
predicted the Y2K bug in 1988! :) Shame it didn't allow me to make any money from the prediction, though...
As a matter of interest the system was written in dBase III, later converted to FoxBase, then to FoxPro, I felt a glitch of pride when I
was able to report that it didn't need anything doing to be Y2K compliant. I don't know if it's still being run, but it could be!
Cheers,
Howard Winter
St.Albans, England
2006\07\27@064557
by
Jinx
> > years divisible by 8,000"
>
> OK, but I think the costbenefit doesn't justify the development
> time. The next time it happens just send me an email and I'll change
> my clocks by hand :)
I have an uneasy feeling that email won't be around in 6,000 years.
We'll be back to scratching glyphs on stone. Which I can do right
now and you could put it aside. Obviously I can't be there to deliver
it in person, but I know someone who was going to throw a brick
through your window anyway, and he owes me so said he'd scribble
a note on it
PS, if you hear a screech of brakes outside, duck
2006\07\27@095314
by
Tamas Rudnai
So what about if you divide by 4 (rrf, so if one of the bit that goes into C
set then it is _not_ leap). If dividable by 4, then substract 100 (as you
need to know mod 400 as well  max 2.5 substractions / 1K years) until you
reach either zero or less than zero. If the result is zero, then you know,
that the year is dividable by 400, so it _is_ a leap year. If not, then you
have the remainder as a negative number, so you negate it (comp +1), then
you can continue the substraction by 25 (aka 100 year  max 4 substractions
as it is the remainder of /400). If the result is zero, then it is not a
leap year, if it is negative then leave it is a leap...
Tamas
On 27/07/06, Brooke Clarke <.....brookeKILLspam@spam@pacific.net> wrote:
{Quote hidden}>
> Hi:
>
> I've recently discovered that the code in Microchip TB028 (and the
> hardware real time clocks that are commonly being sold) only use the 4
> year test for leap year. This will work OK till midnight Feb 28 2100.
> Although I'll be long gone by then it would be nice if a clock could be
> used to determine the day of the week for past and future dates so I'm
> looking for a routine that will determine if a year is a leap year and
> that works from 1582 to 9999+.
>
> A strategy might be to first do a couple of rotate right file operations
> on a 16 bit unsigned integer holding the year in a couple of bytes,
> checking for a carry on each rotate. A carry means not a leap year and
> stop any further calculation.
>
> Then a loop that starts with the shifted year (i.e.. starts with year/4)
> and then subtract 25 repeatedly (i.e. subtracting 100 from the unshifted
> year).
> If the loop terminates with a carry out it's a leap year (i.e. could
> only divide by 4).
> If the loop terminates with a zero remainder the year is divisible by
> 100 so might be a leap year, depending . . .
> If the loop counter rotated right twice generates no carries the year is
> divisible by 400 and is a leap year else it is not a leap year.
>
> I've worked on this all day and am still don't see light at the end of
> the tunnel. I find that status,C is not changed by dec or incf. That
> the meaning of status,C changes depending on what the prior operation
> was. So was hoping that someone has already figured out how to do it?
>
> PS  The LCD hardware commands for cursor and blink on/off are global in
> nature and so can not be on when the LCD is being updated since they
> would be applied to all the characters getting updated. That means they
> are not usable for clock displays. But software blinking, like in
> AN582, does work nicely.
>
> Have Fun,
>
> Brooke
>
> 
> w/Java
http://www.PRC68.com
> w/o Java www.pacificsites.com/~brooke/PRC68COM.shtml
>
http://www.precisionclock.com
>
> 
2006\07\27@125353
by
Brooke Clarke
Hi Jinx:
After doing the 4 year test to eliminate 3/4 of the years a table still
would take up a lot of memory.
Hi Rolf:
Are ALL the numbers in Zeller's congruence integers? Does PIC code for
it exist already?
Hi Tames:
No, I know I'll be dead long before then, BUT I would like to be able to
enter a date in the future and find out what day of the week it falls on.
Hi Russell:
I'm only concerned with the 4, 100 and 400 year tests since these are
"official" as of now.
Hi Tamas:
Yesterday, while debugging the OP strategy the need to add back 0xFF to
the low year byte became apparent when there's a carry after subtracting
25. But before pursuing it further I'm going to try Zeller's congruence.
Thanks very much,
Brooke Clarke

w/Java http://www.PRC68.com
w/o Java www.pacificsites.com/~brooke/PRC68COM.shtml
http://www.precisionclock.com
2006\07\27@132030
by
Rolf
I have not found a PIC ASM version of Zeller's Congruence.... would be
interesting though, wouldn't it.
Sorry
Rolf
P.S. I'll be happy to try
Brooke Clarke wrote:
{Quote hidden}> Hi Jinx:
> After doing the 4 year test to eliminate 3/4 of the years a table still
> would take up a lot of memory.
>
> Hi Rolf:
> Are ALL the numbers in Zeller's congruence integers? Does PIC code for
> it exist already?
>
> Hi Tames:
> No, I know I'll be dead long before then, BUT I would like to be able to
> enter a date in the future and find out what day of the week it falls on.
>
> Hi Russell:
> I'm only concerned with the 4, 100 and 400 year tests since these are
> "official" as of now.
>
> Hi Tamas:
> Yesterday, while debugging the OP strategy the need to add back 0xFF to
> the low year byte became apparent when there's a carry after subtracting
> 25. But before pursuing it further I'm going to try Zeller's congruence.
>
> Thanks very much,
>
> Brooke Clarke
>
2006\07\27@133837
by
Gerhard Fiedler

Brooke Clarke wrote:
> No, I know I'll be dead long before then, BUT I would like to be able to
> enter a date in the future and find out what day of the week it falls on.
Keep in mind that "calendar" and "thousand years" in one sentence is a
thing that should raise some flags :)
For example, for dates farther back than some 100 years, you need to know
where that date was written, which may help you in finding out which
version of the several (similar) calendars in use at the time the date
refers to. (This of course doesn't even take into account all the calendars
that are fundamentally different from the Gregorian/Julian calendars.)
Did you know that George Washington was born on February 11, 1732
(according to the calendar used when he was born)?
Since the history of both the Julian and Gregorian calendars is much more
political than astronomical (which can be expected), and these things have
a tendency to not change, I'd bet my grave stone that 6000 years from now
there will be a different calendar in place :)
Gerhard
2006\07\27@151726
by
William Chops Westfield
On Jul 27, 2006, at 1:27 AM, Russell McMahon wrote:
>> Try Zeller's congruence (Russel's favourite:
>> en.wikipedia.org/wiki/Zeller%27s_Congruence
>>
Hmm. Interesting wiki page. Can anyone see how the "algorithm"
presented matches the formula?
BillW
2006\07\27@194121
by
Jinx
> After doing the 4 year test to eliminate 3/4 of the years a table still
> would take up a lot of memory.
Test for divisibility by 4 (Result = No, not a leap year. Done)
Result = Yes, possibly a leap year. Test century
Do a loop from 12 to 100, with a step of 4. Multiply the loop counter
by 100 and compare the result to the year under test. If result = year
under test, then leap year
Add a compare, loop and step 4 to this code, generated by
http://www.piclist.com/techref/piclist/codegen/constdivmul.htm
; year = year * 100
; Temp = TEMP
; year size = 8 bits
; Error = 0 %
; Bytes order = little endian
; Round = no
; ALGORITHM:
; Clear accumulator
; Add input * 64 to accumulator
; Add input * 32 to accumulator
; Add input * 4 to accumulator
; Move accumulator to result
;
; Approximated constant: 100, Error: 0 %
; Input: year0, 8 bits
; Output: year0 .. year1, 15 bits
; Code size: 32 instructions
cblock
year0
year1
TEMP0
TEMP1
endc
;shift accumulator left 2 times
clrc
rlf year0, f
clrf year1
rlf year1, f
rlf year0, f
rlf year1, f
;copy accumulator to temporary
movf year1, w
movwf TEMP1
movf year0, w
movwf TEMP0
;shift temporary left 3 times
clrc
rlf TEMP0, f
rlf TEMP1, f
rlf TEMP0, f
rlf TEMP1, f
rlf TEMP0, f
rlf TEMP1, f
;add temporary to accumulator
movf TEMP0, w
addwf year0, f
movf TEMP1, w
skpnc
incfsz TEMP1, w
addwf year1, f
;shift temporary left 1 times
clrc
rlf TEMP0, f
rlf TEMP1, f
;add temporary to accumulator
movf TEMP0, w
addwf year0, f
movf TEMP1, w
skpnc
incfsz TEMP1, w
addwf year1, f
2006\07\27@195739
by
Jinx
> After doing the 4 year test to eliminate 3/4 of the years a table
> still would take up a lot of memory.
The second test of my previous reply is obviously way OTT and
the multiplication is completely unnecessary. Same accomplished
by starting with compare value of 1200. Successively add 400 to
this and loop/compare
(a cup of tea and breakfast should be mandatory before thinking)
2006\07\27@222030
by
Gerhard Fiedler

William ChopsWestfield wrote:
> On Jul 27, 2006, at 1:27 AM, Russell McMahon wrote:
>
>>> Try Zeller's congruence (Russel's favourite:
>>> http://en.wikipedia.org/wiki/Zeller%27s_Congruence
>
> Hmm. Interesting wiki page. Can anyone see how the "algorithm"
> presented matches the formula?
> Algorithm Z(y, m, d)
> Input: The year y, month m (1 â‰¤ m â‰¤ 12) and day d (1 â‰¤ d â‰¤ 31).
> Output: The day of the week.
>
> t â† (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4)
This seems to be the "m term" of the formula. But it comes out differently
when I try it. The sequence I get is (5, 0, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5).
Apparently shifted by two positions, and still three of the remaining
numbers different.
> n â† (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
> if m < 3
> y â† y  1
This seems to be related to the "March confusion": up until some time, they
seemed to have considered the year to start with March, so the months
before belonged to the earlier year. Apparently Mr. Zeller created the
formula at that time.
> w â† (y + [y/4]  [y/100] + [y/400] + t(m1) + d) mod 7
Mostly, it seems this is the formula slightly reorganized:
+ y : K in the formula
+ [y/4]: [K/4]
 [y/100] + [y/400]: [J/4]  2J (according to the Analysis section)
+ t(m1): the "m term", changing 1based months to 0based index?
+ d: q
> return n(w)
They say the formula returns 0 for Saturday, whereas here 0 is Sunday?
So this doesn't really explain it, but at least it raises questions :)
Gerhard
2006\07\28@014715
by
Russell McMahon
>> On Jul 27, 2006, at 1:27 AM, Russell McMahon wrote:
>>>> Try Zeller's congruence (Russel's favourite:
>>>> en.wikipedia.org/wiki/Zeller%27s_Congruence
>>
>> Hmm. Interesting wiki page. Can anyone see how the "algorithm"
>> presented matches the formula?
...
No he didn't :)
Looks interesting though.
RM
2006\07\28@034810
by
Alan B. Pearce
>This seems to be related to the "March confusion": up until some time, they
>seemed to have considered the year to start with March, so the months
>before belonged to the earlier year. Apparently Mr. Zeller created the
>formula at that time.
The "march confusion" you cite seems to be a mechanism for making the
calculation easier by adding the extra day to the end of the year, rather
than in the middle of the calculation year., rather than it being an actual
"year start".
It is purely a device to make the calculation easier.
2006\07\28@074348
by
Gerhard Fiedler

Alan B. Pearce wrote:
>>This seems to be related to the "March confusion": up until some time, they
>>seemed to have considered the year to start with March, so the months
>>before belonged to the earlier year. Apparently Mr. Zeller created the
>>formula at that time.
>
> The "march confusion" you cite seems to be a mechanism for making the
> calculation easier by adding the extra day to the end of the year, rather
> than in the middle of the calculation year., rather than it being an actual
> "year start".
>
> It is purely a device to make the calculation easier.
You may be right... I didn't analyze how the formula works, and I didn't
quite understand how the algorithm is related to it.
However, I didn't just make that "March confusion" up; Wikipedia claims in
http://en.wikipedia.org/wiki/Gregorian_calendar that there indeed has been
something like that:
""Old Style" (OS) and "New Style" (NS) are sometimes added to dates to
identify which system is used in the British Empire and other countries
that did not immediately change. In Britain it is usual to map most dates
from the Julian year onto the Gregorian year without converting the day and
month. But because the start of the year did not change until the same year
that the Gregorian calendar was introduced, OS/NS is particularly relevant
for dates which fall between, 1 January and 25 March. For example the
execution of King Charles I is usually recorded as having taken place on
16490130 (NS), but in contemporary documents it is recorded as having
taken place on 30 January 1648[2]."
Gerhard
2006\07\28@093718
by
William Couture
On 7/27/06, Howard Winter <HDRWKILLspamh2org.demon.co.uk> wrote:
>
> Or you could work it out from first principles, if you know the exact (mean) length of a
> Solar Year.
>
> If it was 365.25 it would just be every 4 years.
>
> 365.24 brings in the 100year exception (subtract 1/100 from the above)
>
> 365.2425 adds the 400year part (add 1/400)
>
> and so on.
>
> Googling the exact length of a Solar Year is left as an exercise for the reader! ;)
http://www.astro.uni.torun.pl/~kb/Papers/JRASC/Tropic.htm

Psst... Hey, you... Buddy... Want a kitten? straycatblues.petfinder.org
More... (looser matching)
 Last day of these posts
 In 2006
, 2007 only
 Today
 New search...