Listing 14 5 TestConstructors
Jump to navigation
Jump to search
This is from Chapter 14 of Beginning C for Arduino by Dr. Jack Purdum.
It adds to the implementation of an Arduino library shown in Chapter 12 that calculates both Leap Years and the date Easter occurs in any year, to add Julian date capability.
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" NOTE: You may want to save the existing "Dates" library folder if you want to be able to get back to the Chapter 12 version.
- 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 14-5. Using the Dates Library */ #include "Dates.h" Dates myDates; // This calls the default constructor void setup() { int i; int total; Serial.begin(9600); //Dates myDates; // Default constructor, no initializer //Dates myDates(2015); // Constructor with initializer for (i = 2000; i < 2017; i++) { Serial.print(i); Serial.print(" is "); if (myDates.IsLeapYear(i) == 0) { Serial.print("not "); } Serial.print("a leap year, Easter is on: "); myDates.myEaster.year = i; myDates.GetEaster(&myDates); total = myDates.julian(3, 5, i); Serial.print(myDates.myEaster.easterStr); Serial.print(" jullian days to May 3: "); Serial.println(total); } } void loop() {}
Dates.h:
/* Listing 12-2. The Dates.h header file (Modified in Chapter 14 to add Julian ) 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); char * DayOfTheWeek(int day, int month, int year); char *GetDayOfWeek(); int julian(int day, int month, int year); // New method }; #endif // Don't forget this!
Dates.cpp:
/* Listing 14-3. The Dates.cpp source code Modified to add Julian */ #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... } /***** Listing 14-3. The julian() Method. (Added in Chapter 14) Purpose: Determine the numbers of days between the given date and Jan 1 of the same year. Algorithm taken from C Programmer's Toolkit, Jack Purdum, Que Corp., 1993, p.257. Parameters: int day The day to test int month The month to test int year The year to test (e.g., 2015) Return value: int The number of days, including the one given *****/ int Dates::julian(int day, int month, int year) { static int runsum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; int total; total = runsum[month - 1] + day; if (month > 2) { total += IsLeapYear(year); // Adjust for leap year } return total; }
Expected output of the Dates Library Test:
2000 is a leap year, Easter is on: 04/23/2000 jullian days to May 3: 124 2001 is not a leap year, Easter is on: 04/15/2001 jullian days to May 3: 123 2002 is not a leap year, Easter is on: 03/31/2002 jullian days to May 3: 123 2003 is not a leap year, Easter is on: 04/20/2003 jullian days to May 3: 123 2004 is a leap year, Easter is on: 04/11/2004 jullian days to May 3: 124 2005 is not a leap year, Easter is on: 03/27/2005 jullian days to May 3: 123 2006 is not a leap year, Easter is on: 04/16/2006 jullian days to May 3: 123 2007 is not a leap year, Easter is on: 04/08/2007 jullian days to May 3: 123 2008 is a leap year, Easter is on: 03/23/2008 jullian days to May 3: 124 2009 is not a leap year, Easter is on: 04/12/2009 jullian days to May 3: 123 2010 is not a leap year, Easter is on: 04/04/2010 jullian days to May 3: 123 2011 is not a leap year, Easter is on: 04/24/2011 jullian days to May 3: 123 2012 is a leap year, Easter is on: 04/08/2012 jullian days to May 3: 124 2013 is not a leap year, Easter is on: 03/31/2013 jullian days to May 3: 123 2014 is not a leap year, Easter is on: 04/20/2014 jullian days to May 3: 123 2015 is not a leap year, Easter is on: 04/05/2015 jullian days to May 3: 123 2016 is a leap year, Easter is on: 03/27/2016 jullian days to May 3: 124