Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 02:48 28 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MM - Leap Year Y or N?

     Page 1 of 2    
Author Message
Nixie
Regular Member

Joined: 19/02/2013
Location: Australia
Posts: 66
Posted: 01:25pm 20 Jun 2013
Copy link to clipboard 
Print this post

Hello all,
I am trying to write a quick way of determining if the current year is a Leap Year or not, using MMBasic 4.3A.
I found that if you divide the year by 4, that you get a whole number; and, therefore it is a Leap Year.
If you get a remainder, then it's not.

So is there a simple way to determine if ones answer is a whole number?
Or one with a decimal on the end? For example:
2016/ 4=504 a leap year
2014/ 4=503.5 not a leap year

Many thanks, Nic.
VK3COW on a cattle property in Western Victoria.

"Biggles smiled grimly"
 
Bill.b

Senior Member

Joined: 25/06/2011
Location: Australia
Posts: 226
Posted: 01:49pm 20 Jun 2013
Copy link to clipboard 
Print this post

Look up the MOD function. This will give the remainder of the calculation

therefore if MOd = 0 then it is a leapyear. if any other number
then it is a mormal year.

Also do not forget leap centry. divide by 400.

Bill
In the interests of the environment, this post has been constructed entirely from recycled electrons.
 
kiiid

Guru

Joined: 11/05/2013
Location: United Kingdom
Posts: 671
Posted: 01:53pm 20 Jun 2013
Copy link to clipboard 
Print this post

Leap year by its definition is divisible by 4 and 400, but not divisible by 100.

This is a C function to check it:
return !!(!(year%400) || ((year%100) && !(year%4)));

in MMBasic it will be something like:
IF (year MOD 400 = 0) OR ((year MOD 100 <> 0) AND (year MOD 400 = 0)) THEN ... it's a leap year
Edited by kiiid 2013-06-21
http://rittle.org

--------------
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 04:47pm 20 Jun 2013
Copy link to clipboard 
Print this post

  kiiid said   Leap year by its definition is divisible by 4 and 400, but not divisible by 100.

This is a C function to check it:
return !!(!(year%400) || ((year%100) && !(year%4)));

in MMBasic it will be something like:
IF (year MOD 400 = 0) OR ((year MOD 100 <> 0) AND (year MOD 400 = 0)) THEN ... it's a leap year


I think that should be:
IF (year MOD 400 = 0) OR ((year MOD 100 <> 0) AND (year MOD 4 = 0)) THEN ... it's a leap year

Cheers,
Hugh
 
kiiid

Guru

Joined: 11/05/2013
Location: United Kingdom
Posts: 671
Posted: 04:51pm 20 Jun 2013
Copy link to clipboard 
Print this post

A typo... Sorry.
Hugh is rightEdited by kiiid 2013-06-22
http://rittle.org

--------------
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 07:38pm 20 Jun 2013
Copy link to clipboard 
Print this post

This is one of those ever repeating problems.
Others are like adding a day or month to a date.
For instance as an exercise, what is the date of january 31 2016 plus one month.

Microblocks. Build with logic.
 
kiiid

Guru

Joined: 11/05/2013
Location: United Kingdom
Posts: 671
Posted: 08:01pm 20 Jun 2013
Copy link to clipboard 
Print this post

  TZAdvantage said  
For instance as an exercise, what is the date of january 31 2016 plus one month.


Yes, time measuring, although the most often used measure, is probably one of the worst systems we have today. It's been annoying me for years. Another exercise: try to calculate without a calculator how many hours (or even days) there are between 17 January and 28 August.

I had some thoughts about that here but the social inertia is so huge, that it is impossible to expect any change would be possible. I think many others have tried before...Edited by kiiid 2013-06-22
http://rittle.org

--------------
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 08:18pm 20 Jun 2013
Copy link to clipboard 
Print this post

In Thailand people are very practical. A problem with dates and time is that it is not practical at all.
Ask a Thai person how many weeks there are in 10 years and the answer would be 480.
Because a month has 4 weeks, right. And a year 12 months.
So it must be 4 times 12 times 10.
The big employers are very happy with this you can imagine.
Paying people a monthly wage based on 4 weeks.....
Some think a little longer and say 520 weeks (this would be the common answer in western countries).
Because a year has 52 weeks, right.....
Sigh....
Capturing all that stuff in good library functions, like the one i use very frequently in C# is a life saver.
Don't get me started about Daylight savings and timezones.
The TZ in TZAdvantage stands for Timezone btw as i have a TimeZone Advantage for working on websites. In the Netherlands were most of my websites run people sleep when i modify them.


Microblocks. Build with logic.
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 08:25pm 20 Jun 2013
Copy link to clipboard 
Print this post

And Kiiid, not only social inertia. The scientific inertia is even bigger.
You will upset the Metric world especially that uses a second which is the duration of 9,192,631,770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the cesium 133 atom. The Imperial world would be upset too.
All derived values need to correspond with that 'second'. Like a Newton, Joule, Watt or Coulomb.

Edited by TZAdvantage 2013-06-22
Microblocks. Build with logic.
 
kiiid

Guru

Joined: 11/05/2013
Location: United Kingdom
Posts: 671
Posted: 08:36pm 20 Jun 2013
Copy link to clipboard 
Print this post

TZA, yes, I don't mind upsetting them if necessary. The second as such is a purely artificial measure, derived to accommodate within an existing system, but not as it normally should be - the system built around it. Hence all the problems source at this very basic level. Many attempts have been made before, but they all have tried to build a new system using the old second and of course have failed.
Edited by kiiid 2013-06-22
http://rittle.org

--------------
 
Nixie
Regular Member

Joined: 19/02/2013
Location: Australia
Posts: 66
Posted: 08:53pm 20 Jun 2013
Copy link to clipboard 
Print this post

Whoa! Gentleman! Thank you, thank you, thank you.
I've just come inside to see the posts, giving me the answers. Ah modulus, I learn something every day!

(Winter is very much here! Freezing and windy! I just checked on the cattle and moved the old draught-horses back to their stables for the night. I did chat with them about the Leap Year issue, but all they did was roll their eyes at each other saying 'duh! How does he expect us to help? Hasn't he seen our feet?! ...and he expects us to help on the keyboard! - besides we're too busy nutting out the Heisenberg Uncertainty Principle.')

Sigh.... Much appreciated. Best regards, Nic.

PS I am flattered with the suggestion about allowing for a Leap Century! Not sure if the program I'm writing will last that long <grin>
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 09:12pm 20 Jun 2013
Copy link to clipboard 
Print this post

Anyone want to have a go at an day of the week function?
It is not that hard.

GWBasic and TRS80 days are coming back. I just looked up how to do it and you need to do these 8 steps:
1) Start with three numbers for each part of the date. A day, a month and a year

2 ) If the date is in January or February add 12 to the month number and substract 1 from the year number

3 ) Add 1 to the month and divide by 2.61 and use only the whole number (truncate), do not round!

4 ) Add the Day, Month and the last two digits of the year and assign it to a variable, for instance name it Calc

5) Take the last two digits of the year and divide it by 4 and truncate the result. Then add it to "Calc"

6) You then need to add a number to "Calc" for the different centuries. 18th century add 2, 19th century add 0, 20th century add 6, 21st century add 4

7) Do a MOD 7 on the "Calc" value to get the day of the week.

8) Adjust this value for your local. Some have sunday as day one others use monday as day 1.


Now you can use it to check on which day you where born. If your good in calculations you can even do it in your head, i could when i trained a little. Not anymore though.


Microblocks. Build with logic.
 
BobDevries

Senior Member

Joined: 08/06/2011
Location: Australia
Posts: 266
Posted: 09:16pm 20 Jun 2013
Copy link to clipboard 
Print this post

Heh, I believe that calculation was included in my analogue clock programme. I didn't write it; just rewrote it in MMBasic.

Regards,

Bob Devries
Dalby, QLD, Australia
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 09:18pm 20 Jun 2013
Copy link to clipboard 
Print this post

You can get it out of Wikipedia too. I used it in the RTC in my mono MM.
 
James_From_Canb

Senior Member

Joined: 19/06/2011
Location: Australia
Posts: 265
Posted: 12:25am 21 Jun 2013
Copy link to clipboard 
Print this post

Or, if anyone remembers it, in Knuth's book of algorithms. What a great set of books. They saved me a lot of development time.

James
My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention.

Hedley Lamarr, Blazing Saddles (1974)
 
Nixie
Regular Member

Joined: 19/02/2013
Location: Australia
Posts: 66
Posted: 11:59pm 21 Jun 2013
Copy link to clipboard 
Print this post

TZAdvantage - or anyone else do you have a sequence/algorithm, for determining what the date will be in 24 hrs from a specific time?

So if its 11:30:59 on 30:04:2013, I need to determine the date at 11:30:58 on the next day.

(I have written some code which works, but it is very clumsy! In fact it is awful!)

Thanks, Nic.
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 01:13am 22 Jun 2013
Copy link to clipboard 
Print this post

Look up Julian Date in Wikipedia Convert to Julian Date, add 1 day and convert back. The algorithms are there, they just need a little massaging to suit the MM.
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 02:05am 22 Jun 2013
Copy link to clipboard 
Print this post

  Nixie said   TZAdvantage - or anyone else do you have a sequence/algorithm, for determining what the date will be in 24 hrs from a specific time?

So if its 11:30:59 on 30:04:2013, I need to determine the date at 11:30:58 on the next day.

(I have written some code which works, but it is very clumsy! In fact it is awful!)

Thanks, Nic.

I'll just write down what i think you need.

1 ) Make sure the date/time you start with is valid
2 ) Determine if the day is the last day of the month. Using a small array with a MOnthDays. 31,28,31,30,31,30,31,31,30,31,30,31 (Make sure that if it is a leap year you change the 28 into 29)
3 ) Add 1 to the day. If it is higher then the MonthDays add one to month. If month is higher then 12 change it into 1 and add one to the year.

That should do the trick . Edited by TZAdvantage 2013-06-23
Microblocks. Build with logic.
 
Nixie
Regular Member

Joined: 19/02/2013
Location: Australia
Posts: 66
Posted: 03:40am 22 Jun 2013
Copy link to clipboard 
Print this post

Ah thank you!

BobD - the Julian option came to mind earlier, but slipped away as I became distracted.

TZAdvantage - yes, the use of the array is a good idea!

Well, I will investigate both paths and see which is best.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6100
Posted: 02:09pm 22 Jun 2013
Copy link to clipboard 
Print this post

I played arround with date routines a while ago.
You have to be careful with the limited accuracy of 32 bit floating point maths.

Newdate$= date$

mainloop:
DOW (Newdate$, weekday, day$) ' returns day of week as number and string
splitdate (Newdate$, day, month, year)
toJD (day, month, year, jd) ' returns Julien Day Number
print Newdate$;" "weekday;" ";day$ ;" - JD number: ";format$(jd,"%9.0f")

input "New Date: ", Newdate$
if Newdate$<>"" then goto mainloop

end

' given date as string, returns day, month, year
sub splitdate (currentdate$, d, m, y)
d= val(mid$(currentdate$,1,2))
m= val(mid$(currentdate$,4,2))
y= val(mid$(currentdate$,7,4))
end sub

'given day, month, year
'dayz=days since 1/1/1900 - agrees with Excel after 1/3/1900
sub toMSday (d, m, y, dayz, dayofyear)
dayofyear= d+int((m-1)*30.57+0.5)
if m>2 then
dayofyear= dayofyear-1
if (y mod 4)>0 then dayofyear= dayofyear-1
endif
dayz= int((y-1900)*365.25-0.25)+dayofyear+1
end sub

' given date as string, returns day of week as number and string
sub DOW (currentdate$,weekday, day$)
local d, m, y, dayz
splitdate (currentdate$, d, m, y)
toMSday (d, m, y, dayz, dayofyear)
weekday= abs((dayz-1) mod 7)
day$=mid$("SunMonTueWedThuFriSatSun",weekday*3+1,3)
end sub

' input day, month, year - returns julien day number
sub toJD ( d, m, y, jd)
ff = fix((m-14)/12)
jd = fix((1461*(y+4800+ff))/4)+fix((367*(m-2-12*ff))/12)-fix((3*( fix(y+4900+ff)/100))/4)+d-32075
end sub

'input julien day - returns day, month, year
sub fromJD (jd, d, m, y)
local l, n, i, j
l = jd + 68569
n = fix(( 4 * l ) / 146097)
l = l - fix(( 146097 * n + 3 ) / 4)
i = fix(( 4000 * ( l + 1 ) ) / 1461001)
l = l - fix(( 1461 * i ) / 4 )+ 31
j = fix(( 80 * l ) / 2447)
d = l - fix(( 2447 * j ) / 80)
l = fix(j / 11)
m = j + 2 - ( 12 * l )
y = 100 * ( n - 49 ) + i + l
end sub


Jim
VK7JH
MMedit   MMBasic Help
 
     Page 1 of 2    
Print this page
© JAQ Software 2024