Searching \ for '[PIC] Leap Year Code good for 400 Years?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Leap Year Code good for 400 Years?'.

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

flavicon
face
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

face picon face
> A strategy might be to....

... use a table ?

2006\07\26@232941 by Rolf

face picon face
Brooke Clarke wrote:
> Hi:
>
>  
Try Zeller's congruence (Russel's favourite:
http://en.wikipedia.org/wiki/Zeller%27s_Congruence

Rolf
> Have Fun,
>
> Brooke
>
>  

2006\07\27@041525 by Tamas Rudnai

face picon face
Are you considering to produce something that you expect to be still used in
2100? Most of the devices has 1-3 years lifetime, couple may reach 10-15...
but I might missed the point :-)

Tamas



On 27/07/06, Rolf <spam_OUTlearrTakeThisOuTspamrogers.com> wrote:
{Quote hidden}

> -

2006\07\27@043149 by Russell McMahon

face
flavicon
face
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}

2006\07\27@043215 by Russell McMahon

face
flavicon
face
> Try Zeller's congruence (Russel's favourite:
> http://en.wikipedia.org/wiki/Zeller%27s_Congruence

Russell's 2nd favourite :-)

       RM

2006\07\27@052039 by Jinx

face picon face

> /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

flavicon
face
I seem to remember:

/4 : leap year
/20 : not a leap year
/100 : is

{Quote hidden}

> --

2006\07\27@060147 by Tony Smith

picon face
> 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 1-2-3 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

face
flavicon
picon face
Russell,

On Thu, 27 Jul 2006 20:26:59 +1200, Russell McMahon wrote:

{Quote hidden}

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 100-year exception (subtract 1/100 from the above)

365.2425 adds the 400-year 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

face
flavicon
picon face
Jinx,

On Thu, 27 Jul 2006 21:20:33 +1200, Jinx wrote:

{Quote hidden}

OK, but I think the cost-benefit 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

face
flavicon
picon face
Tony,

On Thu, 27 Jul 2006 20:01:39 +1000, Tony Smith wrote:

>...
> I was a Y2K programmer with prior experience.  Odd.

Me too!  (Forward-Y2K programmer, and Odd :-)

In the late 80's I was developing a system that calculated forward dates 10 years ahead (it was a share-option 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

face picon face
> > years divisible by 8,000"
>
> OK, but I think the cost-benefit 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

face picon face
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 <.....brookeKILLspamspam@spam@pacific.net> wrote:
{Quote hidden}

> -

2006\07\27@125353 by Brooke Clarke

flavicon
face
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

face picon face
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}

2006\07\27@133837 by Gerhard Fiedler

picon face
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

face picon face

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

face picon face
> 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

face picon face

> 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

picon face

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(m-1) + 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(m-1): the "m term", changing 1-based months to 0-based 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

face
flavicon
face
>> 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

face picon face
>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

picon face
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
1649-01-30 (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

face picon face
On 7/27/06, Howard Winter <HDRWspamKILLspamh2org.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 100-year exception (subtract 1/100 from the above)
>
> 365.2425 adds the 400-year 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...