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: AustraliaPosts: 66 |
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: AustraliaPosts: 226 |
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 KingdomPosts: 671 |
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 http://rittle.org -------------- |
||||
shoebuckle Senior Member Joined: 21/01/2012 Location: AustraliaPosts: 189 |
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 KingdomPosts: 671 |
A typo... Sorry. Hugh is right http://rittle.org -------------- |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
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 KingdomPosts: 671 |
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... http://rittle.org -------------- |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
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: ThailandPosts: 2209 |
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. Microblocks. Build with logic. |
||||
kiiid Guru Joined: 11/05/2013 Location: United KingdomPosts: 671 |
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. http://rittle.org -------------- |
||||
Nixie Regular Member Joined: 19/02/2013 Location: AustraliaPosts: 66 |
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: ThailandPosts: 2209 |
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: AustraliaPosts: 266 |
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: AustraliaPosts: 935 |
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: AustraliaPosts: 265 |
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: AustraliaPosts: 66 |
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: AustraliaPosts: 935 |
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: ThailandPosts: 2209 |
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 . Microblocks. Build with logic. |
||||
Nixie Regular Member Joined: 19/02/2013 Location: AustraliaPosts: 66 |
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: AustraliaPosts: 6100 |
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 |