From 9888a031e5af22016f8a99e396ee8f4cfcd32959 Mon Sep 17 00:00:00 2001 From: Saad Imtiaz <53612215+Saad-Imtiaz@users.noreply.github.com> Date: Sat, 9 Sep 2023 22:42:20 +0000 Subject: [PATCH 1/4] added the fullformatedtime capability --- NTPClient.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ NTPClient.h | 15 ++++++++---- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/NTPClient.cpp b/NTPClient.cpp index b435855..7c250a5 100755 --- a/NTPClient.cpp +++ b/NTPClient.cpp @@ -210,3 +210,66 @@ void NTPClient::setRandomPort(unsigned int minValue, unsigned int maxValue) { randomSeed(analogRead(0)); this->_port = random(minValue, maxValue); } + + +void NTPClient::setEpochTime(unsigned long secs) { + this->_currentEpoc = secs; +} + +String NTPClient::getFullFormattedTime(unsigned long secs) +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + + uint16_t year = ti->tm_year + 1900; + String yearStr = String(year); + + uint8_t month = ti->tm_mon + 1; + String monthStr = month < 10 ? "0" + String(month) : String(month); + + uint8_t day = ti->tm_mday; + String dayStr = day < 10 ? "0" + String(day) : String(day); + + uint8_t hours = ti->tm_hour; + String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); + + uint8_t minutes = ti->tm_min; + String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); + + uint8_t seconds = ti->tm_sec; + String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); + + return yearStr + "-" + monthStr + "-" + dayStr + "T" + + hoursStr + ":" + minuteStr + ":" + secondStr + "Z"; +} + +int NTPClient::getYear() +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + int year = ti->tm_year + 1900; + + return year; +} + +int NTPClient::getMonth() +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + int month = (ti->tm_mon + 1) < 10 ? 0 + (ti->tm_mon + 1) : (ti->tm_mon + 1); + + return month; +} + +int NTPClient::getDate() +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + int month = (ti->tm_mday) < 10 ? 0 + (ti->tm_mday) : (ti->tm_mday); + + return month; +} \ No newline at end of file diff --git a/NTPClient.h b/NTPClient.h index a31d32f..e61a323 100755 --- a/NTPClient.h +++ b/NTPClient.h @@ -81,11 +81,13 @@ class NTPClient { */ bool isTimeSet() const; - int getDay() const; - int getHours() const; - int getMinutes() const; - int getSeconds() const; - + int getDay(); + int getHours(); + int getMinutes(); + int getSeconds(); + int getYear(); + int getMonth(); + int getDate(); /** * Changes the time offset. Useful for changing timezones dynamically */ @@ -107,6 +109,9 @@ class NTPClient { */ unsigned long getEpochTime() const; + void setEpochTime(unsigned long secs); + + String getFullFormattedTime(unsigned long secs = 0); /** * Stops the underlying UDP client */ From b0aeb42070451944b3f952435ae6ec5ea7603227 Mon Sep 17 00:00:00 2001 From: Saad Imtiaz <53612215+Saad-Imtiaz@users.noreply.github.com> Date: Sat, 9 Sep 2023 22:52:50 +0000 Subject: [PATCH 2/4] updated --- .travis.yml | 10 + CHANGELOG | 30 +- LICENSE | 9 + NTPClient.cpp | 565 ++++++++++++++++--------------- NTPClient.h | 229 ++++++------- README.md | 99 +++--- examples/Advanced/Advanced.ino | 74 ++-- examples/Advanced/desktop.ini | Bin 0 -> 244 bytes examples/Basic/Basic.ino | 66 ++-- examples/Basic/desktop.ini | Bin 0 -> 244 bytes examples/IsTimeSet/IsTimeSet.ino | 53 --- examples/desktop.ini | Bin 0 -> 244 bytes keywords.txt | 4 - library.json | 24 ++ library.properties | 18 +- 15 files changed, 585 insertions(+), 596 deletions(-) create mode 100644 .travis.yml create mode 100644 LICENSE mode change 100755 => 100644 NTPClient.cpp mode change 100755 => 100644 NTPClient.h create mode 100644 examples/Advanced/desktop.ini create mode 100644 examples/Basic/desktop.ini delete mode 100644 examples/IsTimeSet/IsTimeSet.ino create mode 100644 examples/desktop.ini create mode 100644 library.json diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2d9e478 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: c +sudo: false +before_install: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh) +script: + - build_platform esp8266 +notifications: + email: + on_success: change + on_failure: change diff --git a/CHANGELOG b/CHANGELOG index 6a082d5..57126bf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,15 +1,15 @@ -NTPClient 3.1.0 - 2016.05.31 - -* Added functions for changing the timeOffset and updateInterval later. Thanks @SirUli - -NTPClient 3.0.0 - 2016.04.19 - -* Constructors now require UDP instance argument, to add support for non-ESP8266 boards -* Added optional begin API to override default local port -* Added end API to close UDP socket -* Changed return type of update and forceUpdate APIs to bool, and return success or failure -* Change return type of getDay, getHours, getMinutes, and getSeconds to int - -Older - -* Changes not recorded +NTPClient 3.1.0 - 2016.05.31 + +* Added functions for changing the timeOffset and updateInterval later. Thanks @SirUli + +NTPClient 3.0.0 - 2016.04.19 + +* Constructors now require UDP instance argument, to add support for non-ESP8266 boards +* Added optional begin API to override default local port +* Added end API to close UDP socket +* Changed return type of update and forceUpdate APIs to bool, and return success or failure +* Change return type of getDay, getHours, getMinutes, and getSeconds to int + +Older + +* Changes not recorded diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4bf37a8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright © taranais (https://github.com/taranais) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/NTPClient.cpp b/NTPClient.cpp old mode 100755 new mode 100644 index 7c250a5..2c55b21 --- a/NTPClient.cpp +++ b/NTPClient.cpp @@ -1,275 +1,292 @@ -/** - * The MIT License (MIT) - * Copyright (c) 2015 by Fabrice Weinberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "NTPClient.h" - -NTPClient::NTPClient(UDP& udp) { - this->_udp = &udp; -} - -NTPClient::NTPClient(UDP& udp, long timeOffset) { - this->_udp = &udp; - this->_timeOffset = timeOffset; -} - -NTPClient::NTPClient(UDP& udp, const char* poolServerName) { - this->_udp = &udp; - this->_poolServerName = poolServerName; -} - -NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP) { - this->_udp = &udp; - this->_poolServerIP = poolServerIP; - this->_poolServerName = NULL; -} - -NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset) { - this->_udp = &udp; - this->_timeOffset = timeOffset; - this->_poolServerName = poolServerName; -} - -NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset){ - this->_udp = &udp; - this->_timeOffset = timeOffset; - this->_poolServerIP = poolServerIP; - this->_poolServerName = NULL; -} - -NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval) { - this->_udp = &udp; - this->_timeOffset = timeOffset; - this->_poolServerName = poolServerName; - this->_updateInterval = updateInterval; -} - -NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval) { - this->_udp = &udp; - this->_timeOffset = timeOffset; - this->_poolServerIP = poolServerIP; - this->_poolServerName = NULL; - this->_updateInterval = updateInterval; -} - -void NTPClient::begin() { - this->begin(NTP_DEFAULT_LOCAL_PORT); -} - -void NTPClient::begin(unsigned int port) { - this->_port = port; - - this->_udp->begin(this->_port); - - this->_udpSetup = true; -} - -bool NTPClient::forceUpdate() { - #ifdef DEBUG_NTPClient - Serial.println("Update from NTP Server"); - #endif - - // flush any existing packets - while(this->_udp->parsePacket() != 0) - this->_udp->flush(); - - this->sendNTPPacket(); - - // Wait till data is there or timeout... - byte timeout = 0; - int cb = 0; - do { - delay ( 10 ); - cb = this->_udp->parsePacket(); - if (timeout > 100) return false; // timeout after 1000 ms - timeout++; - } while (cb == 0); - - this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time - - this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); - - unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); - unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); - // combine the four bytes (two words) into a long integer - // this is NTP time (seconds since Jan 1 1900): - unsigned long secsSince1900 = highWord << 16 | lowWord; - - this->_currentEpoc = secsSince1900 - SEVENZYYEARS; - - return true; // return true after successful update -} - -bool NTPClient::update() { - if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval - || this->_lastUpdate == 0) { // Update if there was no update yet. - if (!this->_udpSetup || this->_port != NTP_DEFAULT_LOCAL_PORT) this->begin(this->_port); // setup the UDP client if needed - return this->forceUpdate(); - } - return false; // return false if update does not occur -} - -bool NTPClient::isTimeSet() const { - return (this->_lastUpdate != 0); // returns true if the time has been set, else false -} - -unsigned long NTPClient::getEpochTime() const { - return this->_timeOffset + // User offset - this->_currentEpoc + // Epoch returned by the NTP server - ((millis() - this->_lastUpdate) / 1000); // Time since last update -} - -int NTPClient::getDay() const { - return (((this->getEpochTime() / 86400L) + 4 ) % 7); //0 is Sunday -} -int NTPClient::getHours() const { - return ((this->getEpochTime() % 86400L) / 3600); -} -int NTPClient::getMinutes() const { - return ((this->getEpochTime() % 3600) / 60); -} -int NTPClient::getSeconds() const { - return (this->getEpochTime() % 60); -} - -String NTPClient::getFormattedTime() const { - unsigned long rawTime = this->getEpochTime(); - unsigned long hours = (rawTime % 86400L) / 3600; - String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); - - unsigned long minutes = (rawTime % 3600) / 60; - String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); - - unsigned long seconds = rawTime % 60; - String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); - - return hoursStr + ":" + minuteStr + ":" + secondStr; -} - -void NTPClient::end() { - this->_udp->stop(); - - this->_udpSetup = false; -} - -void NTPClient::setTimeOffset(int timeOffset) { - this->_timeOffset = timeOffset; -} - -void NTPClient::setUpdateInterval(unsigned long updateInterval) { - this->_updateInterval = updateInterval; -} - -void NTPClient::setPoolServerName(const char* poolServerName) { - this->_poolServerName = poolServerName; -} - -void NTPClient::sendNTPPacket() { - // set all bytes in the buffer to 0 - memset(this->_packetBuffer, 0, NTP_PACKET_SIZE); - // Initialize values needed to form NTP request - this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode - this->_packetBuffer[1] = 0; // Stratum, or type of clock - this->_packetBuffer[2] = 6; // Polling Interval - this->_packetBuffer[3] = 0xEC; // Peer Clock Precision - // 8 bytes of zero for Root Delay & Root Dispersion - this->_packetBuffer[12] = 49; - this->_packetBuffer[13] = 0x4E; - this->_packetBuffer[14] = 49; - this->_packetBuffer[15] = 52; - - // all NTP fields have been given values, now - // you can send a packet requesting a timestamp: - if (this->_poolServerName) { - this->_udp->beginPacket(this->_poolServerName, 123); - } else { - this->_udp->beginPacket(this->_poolServerIP, 123); - } - this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE); - this->_udp->endPacket(); -} - -void NTPClient::setRandomPort(unsigned int minValue, unsigned int maxValue) { - randomSeed(analogRead(0)); - this->_port = random(minValue, maxValue); -} - - -void NTPClient::setEpochTime(unsigned long secs) { - this->_currentEpoc = secs; -} - -String NTPClient::getFullFormattedTime(unsigned long secs) -{ - time_t rawtime = this->getEpochTime(); - struct tm *ti; - ti = localtime(&rawtime); - - uint16_t year = ti->tm_year + 1900; - String yearStr = String(year); - - uint8_t month = ti->tm_mon + 1; - String monthStr = month < 10 ? "0" + String(month) : String(month); - - uint8_t day = ti->tm_mday; - String dayStr = day < 10 ? "0" + String(day) : String(day); - - uint8_t hours = ti->tm_hour; - String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); - - uint8_t minutes = ti->tm_min; - String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); - - uint8_t seconds = ti->tm_sec; - String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); - - return yearStr + "-" + monthStr + "-" + dayStr + "T" + - hoursStr + ":" + minuteStr + ":" + secondStr + "Z"; -} - -int NTPClient::getYear() -{ - time_t rawtime = this->getEpochTime(); - struct tm *ti; - ti = localtime(&rawtime); - int year = ti->tm_year + 1900; - - return year; -} - -int NTPClient::getMonth() -{ - time_t rawtime = this->getEpochTime(); - struct tm *ti; - ti = localtime(&rawtime); - int month = (ti->tm_mon + 1) < 10 ? 0 + (ti->tm_mon + 1) : (ti->tm_mon + 1); - - return month; -} - -int NTPClient::getDate() -{ - time_t rawtime = this->getEpochTime(); - struct tm *ti; - ti = localtime(&rawtime); - int month = (ti->tm_mday) < 10 ? 0 + (ti->tm_mday) : (ti->tm_mday); - - return month; +/** + * The MIT License (MIT) + * Copyright (c) 2015 by Fabrice Weinberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "NTPClient.h" + +NTPClient::NTPClient(UDP& udp) { + this->_udp = &udp; +} + +NTPClient::NTPClient(UDP& udp, int timeOffset) { + this->_udp = &udp; + this->_timeOffset = timeOffset; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName) { + this->_udp = &udp; + this->_poolServerName = poolServerName; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName, int timeOffset) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName, int timeOffset, unsigned long updateInterval) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; + this->_updateInterval = updateInterval; +} + +void NTPClient::begin() { + this->begin(NTP_DEFAULT_LOCAL_PORT); +} + +void NTPClient::begin(int port) { + this->_port = port; + + this->_udp->begin(this->_port); + + this->_udpSetup = true; +} + +bool NTPClient::isValid(byte * ntpPacket) +{ + //Perform a few validity checks on the packet + if((ntpPacket[0] & 0b11000000) == 0b11000000) //Check for LI=UNSYNC + return false; + + if((ntpPacket[0] & 0b00111000) >> 3 < 0b100) //Check for Version >= 4 + return false; + + if((ntpPacket[0] & 0b00000111) != 0b100) //Check for Mode == Server + return false; + + if((ntpPacket[1] < 1) || (ntpPacket[1] > 15)) //Check for valid Stratum + return false; + + if( ntpPacket[16] == 0 && ntpPacket[17] == 0 && + ntpPacket[18] == 0 && ntpPacket[19] == 0 && + ntpPacket[20] == 0 && ntpPacket[21] == 0 && + ntpPacket[22] == 0 && ntpPacket[22] == 0) //Check for ReferenceTimestamp != 0 + return false; + + return true; +} + +bool NTPClient::forceUpdate() { + #ifdef DEBUG_NTPClient + Serial.println("Update from NTP Server"); + #endif + // flush any existing packets + while(this->_udp->parsePacket() != 0) + this->_udp->flush(); + this->sendNTPPacket(); + + // Wait till data is there or timeout... + byte timeout = 0; + int cb = 0; + do { + delay ( 10 ); + cb = this->_udp->parsePacket(); + + if(cb > 0) + { + this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); + if(!this->isValid(this->_packetBuffer)) + cb = 0; + } + + if (timeout > 100) return false; // timeout after 1000 ms + timeout++; + } while (cb == 0); + + this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time + + unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); + unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + + this->_currentEpoc = secsSince1900 - SEVENZYYEARS; + + return true; +} + +bool NTPClient::update() { + if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval + || this->_lastUpdate == 0) { // Update if there was no update yet. + if (!this->_udpSetup) this->begin(); // setup the UDP client if needed + return this->forceUpdate(); + } + return true; +} + +unsigned long NTPClient::getEpochTime() { + return this->_timeOffset + // User offset + this->_currentEpoc + // Epoc returned by the NTP server + ((millis() - this->_lastUpdate) / 1000); // Time since last update +} + +int NTPClient::getDay() { + return (((this->getEpochTime() / 86400L) + 4 ) % 7); //0 is Sunday +} +int NTPClient::getHours() { + return ((this->getEpochTime() % 86400L) / 3600); +} +int NTPClient::getMinutes() { + return ((this->getEpochTime() % 3600) / 60); +} +int NTPClient::getSeconds() { + return (this->getEpochTime() % 60); +} + +String NTPClient::getFormattedTime(unsigned long secs) { + unsigned long rawTime = secs ? secs : this->getEpochTime(); + unsigned long hours = (rawTime % 86400L) / 3600; + String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); + + unsigned long minutes = (rawTime % 3600) / 60; + String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); + + unsigned long seconds = rawTime % 60; + String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); + + return hoursStr + ":" + minuteStr + ":" + secondStr; +} + +// Based on https://github.com/PaulStoffregen/Time/blob/master/Time.cpp +// currently assumes UTC timezone, instead of using this->_timeOffset +String NTPClient::getFormattedDate(unsigned long secs) { + unsigned long rawTime = (secs ? secs : this->getEpochTime()) / 86400L; // in days + unsigned long days = 0, year = 1970; + uint8_t month; + static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; + + while((days += (LEAP_YEAR(year) ? 366 : 365)) <= rawTime) + year++; + rawTime -= days - (LEAP_YEAR(year) ? 366 : 365); // now it is days in this year, starting at 0 + days=0; + for (month=0; month<12; month++) { + uint8_t monthLength; + if (month==1) { // february + monthLength = LEAP_YEAR(year) ? 29 : 28; + } else { + monthLength = monthDays[month]; + } + if (rawTime < monthLength) break; + rawTime -= monthLength; + } + String monthStr = ++month < 10 ? "0" + String(month) : String(month); // jan is month 1 + String dayStr = ++rawTime < 10 ? "0" + String(rawTime) : String(rawTime); // day of month + return String(year) + "-" + monthStr + "-" + dayStr + "T" + this->getFormattedTime(secs ? secs : 0) + "Z"; +} + +void NTPClient::end() { + this->_udp->stop(); + + this->_udpSetup = false; +} + +void NTPClient::setTimeOffset(int timeOffset) { + this->_timeOffset = timeOffset; +} + +void NTPClient::setUpdateInterval(unsigned long updateInterval) { + this->_updateInterval = updateInterval; +} + +void NTPClient::sendNTPPacket() { + // set all bytes in the buffer to 0 + memset(this->_packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode + this->_packetBuffer[1] = 0; // Stratum, or type of clock + this->_packetBuffer[2] = 6; // Polling Interval + this->_packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + this->_packetBuffer[12] = 0x49; + this->_packetBuffer[13] = 0x4E; + this->_packetBuffer[14] = 0x49; + this->_packetBuffer[15] = 0x52; + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + this->_udp->beginPacket(this->_poolServerName, 123); //NTP requests are to port 123 + this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE); + this->_udp->endPacket(); +} + +void NTPClient::setEpochTime(unsigned long secs) { + this->_currentEpoc = secs; +} + +String NTPClient::getFullFormattedTime(unsigned long secs) +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + + uint16_t year = ti->tm_year + 1900; + String yearStr = String(year); + + uint8_t month = ti->tm_mon + 1; + String monthStr = month < 10 ? "0" + String(month) : String(month); + + uint8_t day = ti->tm_mday; + String dayStr = day < 10 ? "0" + String(day) : String(day); + + uint8_t hours = ti->tm_hour; + String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); + + uint8_t minutes = ti->tm_min; + String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); + + uint8_t seconds = ti->tm_sec; + String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); + + return yearStr + "-" + monthStr + "-" + dayStr + "T" + + hoursStr + ":" + minuteStr + ":" + secondStr + "Z"; +} + +int NTPClient::getYear() +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + int year = ti->tm_year + 1900; + + return year; +} + +int NTPClient::getMonth() +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + int month = (ti->tm_mon + 1) < 10 ? 0 + (ti->tm_mon + 1) : (ti->tm_mon + 1); + + return month; +} + +int NTPClient::getDate() +{ + time_t rawtime = this->getEpochTime(); + struct tm *ti; + ti = localtime(&rawtime); + int month = (ti->tm_mday) < 10 ? 0 + (ti->tm_mday) : (ti->tm_mday); + + return month; } \ No newline at end of file diff --git a/NTPClient.h b/NTPClient.h old mode 100755 new mode 100644 index e61a323..d747654 --- a/NTPClient.h +++ b/NTPClient.h @@ -1,119 +1,110 @@ -#pragma once - -#include "Arduino.h" - -#include - -#define SEVENZYYEARS 2208988800UL -#define NTP_PACKET_SIZE 48 -#define NTP_DEFAULT_LOCAL_PORT 1337 - -class NTPClient { - private: - UDP* _udp; - bool _udpSetup = false; - - const char* _poolServerName = "pool.ntp.org"; // Default time server - IPAddress _poolServerIP; - unsigned int _port = NTP_DEFAULT_LOCAL_PORT; - long _timeOffset = 0; - - unsigned long _updateInterval = 60000; // In ms - - unsigned long _currentEpoc = 0; // In s - unsigned long _lastUpdate = 0; // In ms - - byte _packetBuffer[NTP_PACKET_SIZE]; - - void sendNTPPacket(); - - public: - NTPClient(UDP& udp); - NTPClient(UDP& udp, long timeOffset); - NTPClient(UDP& udp, const char* poolServerName); - NTPClient(UDP& udp, const char* poolServerName, long timeOffset); - NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval); - NTPClient(UDP& udp, IPAddress poolServerIP); - NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset); - NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval); - - /** - * Set time server name - * - * @param poolServerName - */ - void setPoolServerName(const char* poolServerName); - - /** - * Set random local port - */ - void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535); - - /** - * Starts the underlying UDP client with the default local port - */ - void begin(); - - /** - * Starts the underlying UDP client with the specified local port - */ - void begin(unsigned int port); - - /** - * This should be called in the main loop of your application. By default an update from the NTP Server is only - * made every 60 seconds. This can be configured in the NTPClient constructor. - * - * @return true on success, false on failure - */ - bool update(); - - /** - * This will force the update from the NTP Server. - * - * @return true on success, false on failure - */ - bool forceUpdate(); - - /** - * This allows to check if the NTPClient successfully received a NTP packet and set the time. - * - * @return true if time has been set, else false - */ - bool isTimeSet() const; - - int getDay(); - int getHours(); - int getMinutes(); - int getSeconds(); - int getYear(); - int getMonth(); - int getDate(); - /** - * Changes the time offset. Useful for changing timezones dynamically - */ - void setTimeOffset(int timeOffset); - - /** - * Set the update interval to another frequency. E.g. useful when the - * timeOffset should not be set in the constructor - */ - void setUpdateInterval(unsigned long updateInterval); - - /** - * @return time formatted like `hh:mm:ss` - */ - String getFormattedTime() const; - - /** - * @return time in seconds since Jan. 1, 1970 - */ - unsigned long getEpochTime() const; - - void setEpochTime(unsigned long secs); - - String getFullFormattedTime(unsigned long secs = 0); - /** - * Stops the underlying UDP client - */ - void end(); -}; +#pragma once + +#include "Arduino.h" + +#include + +#define SEVENZYYEARS 2208988800UL +#define NTP_PACKET_SIZE 48 +#define NTP_DEFAULT_LOCAL_PORT 1337 +#define LEAP_YEAR(Y) ( (Y>0) && !(Y%4) && ( (Y%100) || !(Y%400) ) ) + + +class NTPClient { + private: + UDP* _udp; + bool _udpSetup = false; + + const char* _poolServerName = "pool.ntp.org"; // Default time server + int _port = NTP_DEFAULT_LOCAL_PORT; + int _timeOffset = 0; + + unsigned long _updateInterval = 60000; // In ms + + unsigned long _currentEpoc = 0; // In s + unsigned long _lastUpdate = 0; // In ms + + byte _packetBuffer[NTP_PACKET_SIZE]; + + void sendNTPPacket(); + bool isValid(byte * ntpPacket); + + public: + NTPClient(UDP& udp); + NTPClient(UDP& udp, int timeOffset); + NTPClient(UDP& udp, const char* poolServerName); + NTPClient(UDP& udp, const char* poolServerName, int timeOffset); + NTPClient(UDP& udp, const char* poolServerName, int timeOffset, unsigned long updateInterval); + + /** + * Starts the underlying UDP client with the default local port + */ + void begin(); + + /** + * Starts the underlying UDP client with the specified local port + */ + void begin(int port); + + /** + * This should be called in the main loop of your application. By default an update from the NTP Server is only + * made every 60 seconds. This can be configured in the NTPClient constructor. + * + * @return true on success, false on failure + */ + bool update(); + + /** + * This will force the update from the NTP Server. + * + * @return true on success, false on failure + */ + bool forceUpdate(); + + int getDay(); + int getHours(); + int getMinutes(); + int getSeconds(); + int getYear(); + int getMonth(); + int getDate(); + + + /** + * Changes the time offset. Useful for changing timezones dynamically + */ + void setTimeOffset(int timeOffset); + + /** + * Set the update interval to another frequency. E.g. useful when the + * timeOffset should not be set in the constructor + */ + void setUpdateInterval(unsigned long updateInterval); + + /** + * @return secs argument (or 0 for current time) formatted like `hh:mm:ss` + */ + String getFormattedTime(unsigned long secs = 0); + /** + * @return time in seconds since Jan. 1, 1970 + */ + unsigned long getEpochTime(); + + /** + * @return secs argument (or 0 for current date) formatted to ISO 8601 + * like `2004-02-12T15:19:21+00:00` + */ + String getFormattedDate(unsigned long secs = 0); + + /** + * Stops the underlying UDP client + */ + void end(); + + /** + * Replace the NTP-fetched time with seconds since Jan. 1, 1970 + */ + void setEpochTime(unsigned long secs); + + String getFullFormattedTime(unsigned long secs = 0); +}; diff --git a/README.md b/README.md index 0c21179..db2b505 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,47 @@ -# NTPClient - -[![Check Arduino status](https://github.com/arduino-libraries/NTPClient/actions/workflows/check-arduino.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/check-arduino.yml) -[![Compile Examples status](https://github.com/arduino-libraries/NTPClient/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/compile-examples.yml) -[![Spell Check status](https://github.com/arduino-libraries/NTPClient/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/spell-check.yml) - -Connect to an NTP server, here is how: - -```cpp -#include -// change next line to use with another board/shield -#include -//#include // for WiFi shield -//#include // for WiFi 101 shield or MKR1000 -#include - -const char *ssid = ""; -const char *password = ""; - -WiFiUDP ntpUDP; - -// By default 'pool.ntp.org' is used with 60 seconds update interval and -// no offset -NTPClient timeClient(ntpUDP); - -// You can specify the time server pool and the offset, (in seconds) -// additionally you can specify the update interval (in milliseconds). -// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); - -void setup(){ - Serial.begin(115200); - WiFi.begin(ssid, password); - - while ( WiFi.status() != WL_CONNECTED ) { - delay ( 500 ); - Serial.print ( "." ); - } - - timeClient.begin(); -} - -void loop() { - timeClient.update(); - - Serial.println(timeClient.getFormattedTime()); - - delay(1000); -} -``` - -## Function documentation -`getEpochTime` returns the Unix epoch, which are the seconds elapsed since 00:00:00 UTC on 1 January 1970 (leap seconds are ignored, every day is treated as having 86400 seconds). **Attention**: If you have set a time offset this time offset will be added to your epoch timestamp. +# NTPClient + +[![Build Status](https://travis-ci.org/arduino-libraries/NTPClient.svg?branch=master)](https://travis-ci.org/arduino-libraries/NTPClient) + +Connect to a NTP server, here is how: + +```cpp +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; + +// By default 'pool.ntp.org' is used with 60 seconds update interval and +// no offset +NTPClient timeClient(ntpUDP); + +// You can specify the time server pool and the offset, (in seconds) +// additionaly you can specify the update interval (in milliseconds). +// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); + +void setup(){ + Serial.begin(115200); + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} +``` diff --git a/examples/Advanced/Advanced.ino b/examples/Advanced/Advanced.ino index 18a6a97..a134395 100644 --- a/examples/Advanced/Advanced.ino +++ b/examples/Advanced/Advanced.ino @@ -1,37 +1,37 @@ -#include -// change next line to use with another board/shield -#include -//#include // for WiFi shield -//#include // for WiFi 101 shield or MKR1000 -#include - -const char *ssid = ""; -const char *password = ""; - -WiFiUDP ntpUDP; - -// You can specify the time server pool and the offset (in seconds, can be -// changed later with setTimeOffset() ). Additionally you can specify the -// update interval (in milliseconds, can be changed using setUpdateInterval() ). -NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); - -void setup(){ - Serial.begin(115200); - - WiFi.begin(ssid, password); - - while ( WiFi.status() != WL_CONNECTED ) { - delay ( 500 ); - Serial.print ( "." ); - } - - timeClient.begin(); -} - -void loop() { - timeClient.update(); - - Serial.println(timeClient.getFormattedTime()); - - delay(1000); -} +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; + +// You can specify the time server pool and the offset (in seconds, can be +// changed later with setTimeOffset() ). Additionaly you can specify the +// update interval (in milliseconds, can be changed using setUpdateInterval() ). +NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); + +void setup(){ + Serial.begin(115200); + + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} diff --git a/examples/Advanced/desktop.ini b/examples/Advanced/desktop.ini new file mode 100644 index 0000000000000000000000000000000000000000..3a9aa42369b35d161d4408c93f23a93b65e2a996 GIT binary patch literal 244 zcmY+9F$%&!5Jg`tc!wN7f+#jZDkYLi(b8Ci5H+AijEcwiWebB0vpYNU{@>j_F+0vw zT#SWT&>9&xjx-z?GO*u-bIpS*DYab1nmY;OKxCAG+1hWdUXrDCqIOQs#&g5Twa_8@ xd9=<}PP$p=nX{Csd0Y2XCVOvC=~(L1E-VpSh=#6-IL%@=t(DO~^n literal 0 HcmV?d00001 diff --git a/examples/Basic/Basic.ino b/examples/Basic/Basic.ino index f0a2a7c..8973c81 100644 --- a/examples/Basic/Basic.ino +++ b/examples/Basic/Basic.ino @@ -1,33 +1,33 @@ -#include -// change next line to use with another board/shield -#include -//#include // for WiFi shield -//#include // for WiFi 101 shield or MKR1000 -#include - -const char *ssid = ""; -const char *password = ""; - -WiFiUDP ntpUDP; -NTPClient timeClient(ntpUDP); - -void setup(){ - Serial.begin(115200); - - WiFi.begin(ssid, password); - - while ( WiFi.status() != WL_CONNECTED ) { - delay ( 500 ); - Serial.print ( "." ); - } - - timeClient.begin(); -} - -void loop() { - timeClient.update(); - - Serial.println(timeClient.getFormattedTime()); - - delay(1000); -} +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP); + +void setup(){ + Serial.begin(115200); + + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} diff --git a/examples/Basic/desktop.ini b/examples/Basic/desktop.ini new file mode 100644 index 0000000000000000000000000000000000000000..3a9aa42369b35d161d4408c93f23a93b65e2a996 GIT binary patch literal 244 zcmY+9F$%&!5Jg`tc!wN7f+#jZDkYLi(b8Ci5H+AijEcwiWebB0vpYNU{@>j_F+0vw zT#SWT&>9&xjx-z?GO*u-bIpS*DYab1nmY;OKxCAG+1hWdUXrDCqIOQs#&g5Twa_8@ xd9=<}PP$p=nX{Csd0Y2XCVOvC=~(L1E-VpSh=#6-IL%@=t(DO~^n literal 0 HcmV?d00001 diff --git a/examples/IsTimeSet/IsTimeSet.ino b/examples/IsTimeSet/IsTimeSet.ino deleted file mode 100644 index 619bfde..0000000 --- a/examples/IsTimeSet/IsTimeSet.ino +++ /dev/null @@ -1,53 +0,0 @@ -#include -// change next line to use with another board/shield -#include -//#include // for WiFi shield -//#include // for WiFi 101 shield or MKR1000 -#include - -const char *ssid = ""; -const char *password = ""; - -WiFiUDP ntpUDP; -// initialized to a time offset of 10 hours -NTPClient timeClient(ntpUDP,"pool.ntp.org", 36000, 60000); -// HH:MM:SS -// timeClient initializes to 10:00:00 if it does not receive an NTP packet -// before the 100ms timeout. -// without isTimeSet() the LED would be switched on, although the time -// was not yet set correctly. - -// blue LED on ESP-12F -const int led = 2; -const int hour = 10; -const int minute = 0; - -void setup(){ - Serial.begin(115200); - - pinMode(led, OUTPUT); - // led is off when pin is high - digitalWrite(led, 1); - - WiFi.begin(ssid, password); - - while (WiFi.status() != WL_CONNECTED) { - delay (500); - Serial.print ("."); - } - - timeClient.begin(); -} - -void loop() { - timeClient.update(); - - Serial.println(timeClient.getFormattedTime()); - if(timeClient.isTimeSet()) { - if (hour == timeClient.getHours() && minute == timeClient.getMinutes()) { - digitalWrite(led, 0); - } - } - - delay(1000); -} diff --git a/examples/desktop.ini b/examples/desktop.ini new file mode 100644 index 0000000000000000000000000000000000000000..3a9aa42369b35d161d4408c93f23a93b65e2a996 GIT binary patch literal 244 zcmY+9F$%&!5Jg`tc!wN7f+#jZDkYLi(b8Ci5H+AijEcwiWebB0vpYNU{@>j_F+0vw zT#SWT&>9&xjx-z?GO*u-bIpS*DYab1nmY;OKxCAG+1hWdUXrDCqIOQs#&g5Twa_8@ xd9=<}PP$p=nX{Csd0Y2XCVOvC=~(L1E-VpSh=#6-IL%@=t(DO~^n literal 0 HcmV?d00001 diff --git a/keywords.txt b/keywords.txt index edce989..1430d04 100644 --- a/keywords.txt +++ b/keywords.txt @@ -12,13 +12,9 @@ begin KEYWORD2 end KEYWORD2 update KEYWORD2 forceUpdate KEYWORD2 -isTimeSet KEYWORD2 getDay KEYWORD2 getHours KEYWORD2 getMinutes KEYWORD2 getSeconds KEYWORD2 getFormattedTime KEYWORD2 getEpochTime KEYWORD2 -setTimeOffset KEYWORD2 -setUpdateInterval KEYWORD2 -setPoolServerName KEYWORD2 diff --git a/library.json b/library.json new file mode 100644 index 0000000..594e2e0 --- /dev/null +++ b/library.json @@ -0,0 +1,24 @@ +{ + "name": "NTPClient", + "keywords": "ntp, client, time", + "description": "A NTPClient to connect to a time server", + "authors": + [ + { + "name": "Fabrice Weinberg", + "email": "fabrice@weinberg.me" + }, + { + "name": "Sandeep Mistry", + "email": "s.mistry@arduino.cc" + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/arduino-libraries/NTPClient.git" + }, + "version": "3.1.0", + "frameworks": "arduino", + "platforms": "espressif" +} diff --git a/library.properties b/library.properties index abdd80d..251e30e 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ -name=NTPClient -version=3.2.1 -author=Fabrice Weinberg -maintainer=Fabrice Weinberg -sentence=An NTPClient to connect to a time server -paragraph=Get time from a NTP server and keep it in sync. -category=Timing -url=https://github.com/arduino-libraries/NTPClient -architectures=* +name=NTPClient +version=3.1.0 +author=Fabrice Weinberg +maintainer=Fabrice Weinberg +sentence=An NTPClient to connect to a time server +paragraph=Get time from a NTP server and keep it in sync. +category=Timing +url=https://github.com/arduino-libraries/NTPClient +architectures=* From 8218bf55ab8445339996ff5fd1fe3c346937656c Mon Sep 17 00:00:00 2001 From: Saad Imtiaz <53612215+Saad-Imtiaz@users.noreply.github.com> Date: Sat, 9 Sep 2023 23:00:00 +0000 Subject: [PATCH 3/4] deleted stange files --- CHANGELOG | 2 ++ examples/Advanced/desktop.ini | Bin 244 -> 0 bytes examples/Basic/desktop.ini | Bin 244 -> 0 bytes examples/desktop.ini | Bin 244 -> 0 bytes keywords.txt | 5 +++++ 5 files changed, 7 insertions(+) delete mode 100644 examples/Advanced/desktop.ini delete mode 100644 examples/Basic/desktop.ini delete mode 100644 examples/desktop.ini diff --git a/CHANGELOG b/CHANGELOG index 57126bf..aab3804 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ + + NTPClient 3.1.0 - 2016.05.31 * Added functions for changing the timeOffset and updateInterval later. Thanks @SirUli diff --git a/examples/Advanced/desktop.ini b/examples/Advanced/desktop.ini deleted file mode 100644 index 3a9aa42369b35d161d4408c93f23a93b65e2a996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmY+9F$%&!5Jg`tc!wN7f+#jZDkYLi(b8Ci5H+AijEcwiWebB0vpYNU{@>j_F+0vw zT#SWT&>9&xjx-z?GO*u-bIpS*DYab1nmY;OKxCAG+1hWdUXrDCqIOQs#&g5Twa_8@ xd9=<}PP$p=nX{Csd0Y2XCVOvC=~(L1E-VpSh=#6-IL%@=t(DO~^n diff --git a/examples/Basic/desktop.ini b/examples/Basic/desktop.ini deleted file mode 100644 index 3a9aa42369b35d161d4408c93f23a93b65e2a996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmY+9F$%&!5Jg`tc!wN7f+#jZDkYLi(b8Ci5H+AijEcwiWebB0vpYNU{@>j_F+0vw zT#SWT&>9&xjx-z?GO*u-bIpS*DYab1nmY;OKxCAG+1hWdUXrDCqIOQs#&g5Twa_8@ xd9=<}PP$p=nX{Csd0Y2XCVOvC=~(L1E-VpSh=#6-IL%@=t(DO~^n diff --git a/examples/desktop.ini b/examples/desktop.ini deleted file mode 100644 index 3a9aa42369b35d161d4408c93f23a93b65e2a996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmY+9F$%&!5Jg`tc!wN7f+#jZDkYLi(b8Ci5H+AijEcwiWebB0vpYNU{@>j_F+0vw zT#SWT&>9&xjx-z?GO*u-bIpS*DYab1nmY;OKxCAG+1hWdUXrDCqIOQs#&g5Twa_8@ xd9=<}PP$p=nX{Csd0Y2XCVOvC=~(L1E-VpSh=#6-IL%@=t(DO~^n diff --git a/keywords.txt b/keywords.txt index 1430d04..d1af6c3 100644 --- a/keywords.txt +++ b/keywords.txt @@ -18,3 +18,8 @@ getMinutes KEYWORD2 getSeconds KEYWORD2 getFormattedTime KEYWORD2 getEpochTime KEYWORD2 +isTimeSet KEYWORD2 +setTimeOffset KEYWORD2 +setUpdateInterval KEYWORD2 +setPoolServerName KEYWORD2 +getFullFormattedTime KEYWORD2 \ No newline at end of file From 73ab3712c94aa8b14fec60b335d195461a3b71fc Mon Sep 17 00:00:00 2001 From: Saad Imtiaz <53612215+Saad-Imtiaz@users.noreply.github.com> Date: Sat, 9 Sep 2023 23:05:12 +0000 Subject: [PATCH 4/4] removed the Z at the end the FullFormattedTime() --- NTPClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NTPClient.cpp b/NTPClient.cpp index 2c55b21..ac398b4 100644 --- a/NTPClient.cpp +++ b/NTPClient.cpp @@ -258,7 +258,7 @@ String NTPClient::getFullFormattedTime(unsigned long secs) String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); return yearStr + "-" + monthStr + "-" + dayStr + "T" + - hoursStr + ":" + minuteStr + ":" + secondStr + "Z"; + hoursStr + ":" + minuteStr + ":" + secondStr; } int NTPClient::getYear()