Listing 12 4 TestDatesLibrary
Jump to navigation
Jump to search
This is from Chapter 12 of Beginning C with Arduino by Dr. Jack Purdum.
It shows the implementation of an Arduino library that calculates both Leap Years and the date Easter occurs in any year.
There are 3 source files here:
- The Arduino Sketch to test the "Dates" library
- The Dates.h header file
- The Dates.cpp Library source file
These files are shown below. To run and test the Dates library you must:
- Create a folder within the Arduino IDE 'libraries' folder named "Dates"
- Copy and paste the .h and .cpp listings below into text files, naming them with their .h and .cpp extensions
- Copy those two files inside the 'Dates' folder
- Close and restart the Arduino IDE
- Copy and paste the test sketch below into a new Arduino IDE window.
- Verify and upload the sketch. The expected output is shown at the end of this page.
DatesTestSketch:
/* Listing 12-4. A program to test the Dates library routine */ #include <Dates.h> Dates myDates; void setup() { int i; Serial.begin(9600); for (i = 2000; i < 2016; i++) { Serial.print(i); Serial.print(" is "); if (myDates.IsLeapYear(i) == 0) Serial.print("not "); Serial.print("a leap year and Easter is on "); myDates.myEaster.year = i; myDates.GetEaster(&myDates); Serial.print(myDates.myEaster.easterStr); Serial.print(" "); Serial.print(myDates.myEaster.month); Serial.print(" "); Serial.print(myDates.myEaster.day); Serial.print(" "); Serial.println(myDates.myEaster.year); } } void loop() {}
Dates.h:
/* Listing 12-2. The Dates.h header file Dates.h - Library for finding is a year is a leap year and the date for Easter for a given year. Created and modified by: Dr. Jack Purdum, Dec. 25, 2014 Released into the public domain. */ #ifndef Dates_h // If we haven't read this file before... #define Dates_h // ...read it now. This prevents double-including #include "Arduino.h" // Not needed for our code, but often included class Dates { public: #define ASCIIZERO 48 // character for 0 in ASCII struct easter { int month; int day; int year; int leap; char easterStr[11]; }; struct easter myEaster; // Function prototypes: int IsLeapYear(int year); void GetEaster(Dates *myEaster); }; #endif // Don't forget this!
Dates.cpp:
/* Listing 12-3. The Dates.cpp source code */ #include "Arduino.h" #include "Dates.h" /***** Purpose: Determine if a given year is a leap year. Algorithm taken from C Programmer's Toolkit, Jack Purdum, Que Corp., 1993, p.258. Parameters: int year The year to test Return value: int 1 if the year is a leap year, 0 otherwise *****/ int Dates::IsLeapYear(int year) { if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { return 1; // It is a leap year } else { return 0; // not a leap year } } /***** Purpose: Determine the date for Easter for a given year. Algorithm taken from Beginning Object Oriented Programming with C#, Jack Purdum, Wrox, 2012. Parameters: struct easter *myData Pointer to an easter structure Return value: void CAUTION: This function assumes that the year member of the structure holds the year being tested upon entry. *****/ void Dates::GetEaster(Dates *myData){ // This is line 44 int offset; int leap; int day; int temp1, temp2, total; myData->myEaster.easterStr[0] = '0'; // Always a '0' myData->myEaster.easterStr[2] = '/'; // Always a '/' myData->myEaster.easterStr[3] = '0'; // Assume day is less than 10 myData->myEaster.easterStr[10] = '\0'; // null char for End of string offset = myData->myEaster.year % 19; leap = myData->myEaster.year % 4; day = myData->myEaster.year % 7; temp1 = (19 * offset + 24) % 30; temp2 = (2 * leap + 4 * day + 6 * temp1 + 5) % 7; total = (22 + temp1 + temp2); if (total > 31) { myData->myEaster.easterStr[1] = '4'; // Must be in April myData->myEaster.month = 4; // Save the month day = total - 31; } else { myData->myEaster.easterStr[1] = '3'; // Must be in March myData->myEaster.month = 3; // Save the month day = total; } myData->myEaster.day = day; // Save the day if (day < 10) { // One day char or two? myData->myEaster.easterStr[4] = (char) (day + ASCIIZERO); } else { itoa(day, myData->myEaster.easterStr + 3, 10); // Convert day to ASCII and... } myData->myEaster.easterStr[5] = '/'; // Always a '/' and overwrites null from itoa() itoa(myData->myEaster.year, myData->myEaster.easterStr + 6, 10); // Convert year to ASCII... }
Expected output of the Dates Library Test:
2000 is a leap year and Easter is on 04/23/2000 4 23 2000 2001 is not a leap year and Easter is on 04/15/2001 4 15 2001 2002 is not a leap year and Easter is on 03/31/2002 3 31 2002 2003 is not a leap year and Easter is on 04/20/2003 4 20 2003 2004 is a leap year and Easter is on 04/11/2004 4 11 2004 2005 is not a leap year and Easter is on 03/27/2005 3 27 2005 2006 is not a leap year and Easter is on 04/16/2006 4 16 2006 2007 is not a leap year and Easter is on 04/08/2007 4 8 2007 2008 is a leap year and Easter is on 03/23/2008 3 23 2008 2009 is not a leap year and Easter is on 04/12/2009 4 12 2009 2010 is not a leap year and Easter is on 04/04/2010 4 4 2010 2011 is not a leap year and Easter is on 04/24/2011 4 24 2011 2012 is a leap year and Easter is on 04/08/2012 4 8 2012 2013 is not a leap year and Easter is on 03/31/2013 3 31 2013 2014 is not a leap year and Easter is on 04/20/2014 4 20 2014 2015 is not a leap year and Easter is on 04/05/2015 4 5 2015