diff --git a/Timestamps.cpp b/Timestamps.cpp new file mode 100644 index 0000000..feb8688 --- /dev/null +++ b/Timestamps.cpp @@ -0,0 +1,108 @@ +/* + Timestamps.cpp - Library for getting both UNIX and NTP timestamps. + Created by Stefan Herzog, April 16 2020. + Released into the public domain. +*/ + +#include "Arduino.h" +#include "Timestamps.h" + +Timestamps::Timestamps(int timeZoneOffset=0) { + _timeZoneOffset = timeZoneOffset; +} + +bool Timestamps::isLeapYear(unsigned int year) { +if (year % 4 == 0) { + if (year % 100 == 0) { + if (year % 400 == 0) { + return true; + } + else { + return false; + } + } + else { + return true; + } +} +else { + return false; +} +} + +unsigned int Timestamps::getTimestamp(int referenceYear, int year, int month, int day, int hour, int minute, int second, int timeZoneOffset=0) { + unsigned int timestamp=0; + // Either use the time zone offset value from instantiating or the given paramter + /* + 1. _timeZoneOffset is set AND timeZoneOffset is set -> use timeZoneOffset + 2. _timeZoneOffset is set AND timeZoneOffset is NOT set -> use _timeZoneOffset + 3. _timeZoneOffset is NOT set AND timeZoneOffset is set -> use timeZoneOffset + 4. _timeZoneOffset is NOT set AND timeZoneOffset is NOT set -> use timeZoneOffset + */ + if(_timeZoneOffset != 0 && timeZoneOffset != 0) { + timeZoneOffset = timeZoneOffset; + } + else if(_timeZoneOffset != 0 && timeZoneOffset == 0) { + timeZoneOffset = _timeZoneOffset; + } + else if(_timeZoneOffset == 0 && timeZoneOffset != 0) { + timeZoneOffset = _timeZoneOffset; + } + else if(_timeZoneOffset == 0 && timeZoneOffset == 0) { + timeZoneOffset = timeZoneOffset; + } + else { + // ERROR + } + + timestamp += timeZoneOffset; + + day <= 0 ? day=0 : day=day-1; + hour <= 0 ? hour=0 : hour=hour-1; + + for(int y=referenceYear; y add one day to timestamp + timestamp += secondsPerDay; + } + } + + for(int m=1; m<=month; m++) { + if(month == 1) { + // we're still in January + timestamp += day * secondsPerDay; // time until yesterday evening / tonight 0:00 + timestamp += hour * secondsPerHour; + timestamp += minute*60; + timestamp += second; + } + if(month > 1) { + timestamp += daysPerMonth[m-1] * secondsPerDay; // last month + + timestamp += day * secondsPerDay; // time until yesterday evening / tonight 0:00 + timestamp += hour * secondsPerHour; + timestamp += minute*60; + timestamp += second; + + if(isLeapYear(year) == 0 && month == 3) { + // current year is leap year, so 29.02. exists + // Since we're in March now, add the 29.02. to the timestamp + timestamp += secondsPerDay; // 29.02. + } + } + } + return timestamp; +} + +unsigned int Timestamps::getTimestampUNIX(int year, int month, int day, int hour, int minute, int second, int timeZoneOffset=0) { +return getTimestamp(1970, year, month, day, hour, minute, second, timeZoneOffset); +} + +unsigned int Timestamps::getTimestampNTP(int year, int month, int day, int hour, int minute, int second, int timeZoneOffset=0) { +return getTimestamp(1900, year, month, day, hour, minute, second, timeZoneOffset); +} + +int Timestamps::secondsPerHour = 60*60; +int Timestamps::secondsPerDay = 24 * secondsPerHour; +int Timestamps::daysPerMonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; diff --git a/Timestamps.h b/Timestamps.h new file mode 100644 index 0000000..67cf34c --- /dev/null +++ b/Timestamps.h @@ -0,0 +1,20 @@ +#ifndef timestamps_h +#define timestamps_h + +#include "Arduino.h" + +class Timestamps { + public: + Timestamps(int setTimeZoneOffset); + unsigned int getTimestampUNIX(int year, int month, int day, int hour, int minute, int second, int setTimeZoneOffset); + unsigned int getTimestampNTP(int year, int month, int day, int hour, int minute, int second, int setTimeZoneOffset); + bool isLeapYear(unsigned int year); + private: + unsigned int getTimestamp(int referenceYear, int year, int month, int day, int hour, int minute, int second, int setTimeZoneOffset); + static int secondsPerHour; + static int secondsPerDay; + static int daysPerMonth[12]; + int _timeZoneOffset; + }; + +#endif diff --git a/examples/getTimestamps.ino b/examples/getTimestamps.ino new file mode 100644 index 0000000..35e56e9 --- /dev/null +++ b/examples/getTimestamps.ino @@ -0,0 +1,30 @@ +/* +Here's an example of how to generate two timestamps: +1. UNIX-timestamp: Used by most clients like servers etc. +2. NTP-timestamp: Can be retrieved by network-shields and calls to a NTP server +*/ + +#include + +Timestamps ts(3600); // instantiating object of class Timestamp with an time offset of 3.600 seconds for Western Eurpean Time + +void setup() { + Serial.begin(115200); + while(!Serial) { + // While serial port is not ready yet, wait a time for it + delay(100); + } +} + +void loop() { + Serial.print("UNIX timestamp: "); + // Get the timestamp for the given date (11. January 2020) and time (14:30:20) + Serial.println(getTimestampUNIX(2020, 1, 25, 14, 30, 20)); // returns: 1579962620 (remember the given offset of 3600 seconds in line 9) + + Serial.print("UNIX timestamp without offset: "); + // You can also use a specified time offset, here "0" as last parameter + Serial.println(getTimestampUNIX(2020, 1, 25, 14, 30, 20, 0)); // returns: 1579959020 (notice the given offset of 0 [last parameter]) + + Serial.print("NTP timestamp: "); + Serial.println(getTimestampNTP(2020, 1, 25, 14, 30, 20)); // returns: 3788951420 (remember the given offset of 3600 seconds in line 9) +} diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..8c72c10 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,3 @@ +Timestamps KEYWORD1 +getTimestampUNIX KEYWORD2 +getTimestampNTP KEYWORD2 \ No newline at end of file