1.9.0 web - new implementation

This commit is contained in:
Paul
2019-08-02 09:26:13 +02:00
parent 89818b23bd
commit fc52f05453
41 changed files with 7206 additions and 931 deletions

185
src/TimeLib.cpp Normal file
View File

@@ -0,0 +1,185 @@
#include "TimeLib.h"
static tmElements_t tm; // a cache of time elements
static time_t cacheTime; // the time the cache was updated
static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds
static uint32_t sysTime = 0;
static uint32_t prevMillis = 0;
static uint32_t nextSyncTime = 0;
static timeStatus_t Status = timeNotSet;
getExternalTime getTimePtr; // pointer to external sync function
#define LEAP_YEAR(Y) (((1970 + (Y)) > 0) && !((1970 + (Y)) % 4) && (((1970 + (Y)) % 100) || !((1970 + (Y)) % 400)))
static const uint8_t monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // API starts months from 1, this array starts from 0
time_t now() {
// calculate number of seconds passed since last call to now()
while (millis() - prevMillis >= 1000) {
// millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference
sysTime++;
prevMillis += 1000;
}
if (nextSyncTime <= sysTime) {
if (getTimePtr != 0) {
time_t t = getTimePtr();
if (t != 0) {
setTime(t);
} else {
nextSyncTime = sysTime + syncInterval;
Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync;
}
}
}
return (time_t)sysTime;
}
// indicates if time has been set and recently synchronized
timeStatus_t timeStatus() {
now(); // required to actually update the status
return Status;
}
void setSyncProvider(getExternalTime getTimeFunction) {
getTimePtr = getTimeFunction;
nextSyncTime = sysTime;
now(); // this will sync the clock
}
void setSyncInterval(time_t interval) { // set the number of seconds between re-sync
syncInterval = (uint32_t)interval;
nextSyncTime = sysTime + syncInterval;
}
void breakTime(time_t timeInput, tmElements_t & tm) {
// break the given time_t into time components
// this is a more compact version of the C library localtime function
// note that year is offset from 1970 !!!
uint8_t year;
uint8_t month, monthLength;
uint32_t time;
unsigned long days;
time = (uint32_t)timeInput;
tm.Second = time % 60;
time /= 60; // now it is minutes
tm.Minute = time % 60;
time /= 60; // now it is hours
tm.Hour = time % 24;
time /= 24; // now it is days
tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1
year = 0;
days = 0;
while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
year++;
}
tm.Year = year; // year is offset from 1970
days -= LEAP_YEAR(year) ? 366 : 365;
time -= days; // now it is days in this year, starting at 0
days = 0;
month = 0;
monthLength = 0;
for (month = 0; month < 12; month++) {
if (month == 1) { // february
if (LEAP_YEAR(year)) {
monthLength = 29;
} else {
monthLength = 28;
}
} else {
monthLength = monthDays[month];
}
if (time >= monthLength) {
time -= monthLength;
} else {
break;
}
}
tm.Month = month + 1; // jan is month 1
tm.Day = time + 1; // day of month
}
time_t makeTime(const tmElements_t & tm) {
// assemble time elements into time_t
// note year argument is offset from 1970 (see macros in time.h to convert to other formats)
// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
int i;
uint32_t seconds;
// seconds from 1970 till 1 jan 00:00:00 of the given year
seconds = tm.Year * (SECS_PER_DAY * 365);
for (i = 0; i < tm.Year; i++) {
if (LEAP_YEAR(i)) {
seconds += SECS_PER_DAY; // add extra days for leap years
}
}
// add days for this year, months start from 1
for (i = 1; i < tm.Month; i++) {
if ((i == 2) && LEAP_YEAR(tm.Year)) {
seconds += SECS_PER_DAY * 29;
} else {
seconds += SECS_PER_DAY * monthDays[i - 1]; //monthDay array starts from 0
}
}
seconds += (tm.Day - 1) * SECS_PER_DAY;
seconds += tm.Hour * SECS_PER_HOUR;
seconds += tm.Minute * SECS_PER_MIN;
seconds += tm.Second;
return (time_t)seconds;
}
void refreshCache(time_t t) {
if (t != cacheTime) {
breakTime(t, tm);
cacheTime = t;
}
}
int day(time_t t) { // the day for the given time (0-6)
refreshCache(t);
return tm.Day;
}
int month(time_t t) { // the month for the given time
refreshCache(t);
return tm.Month;
}
int second(time_t t) { // the second for the given time
refreshCache(t);
return tm.Second;
}
int minute(time_t t) { // the minute for the given time
refreshCache(t);
return tm.Minute;
}
int hour(time_t t) { // the hour for the given time
refreshCache(t);
return tm.Hour;
}
int weekday(time_t t) {
refreshCache(t);
return tm.Wday;
}
int year(time_t t) { // the year for the given time
refreshCache(t);
return tmYearToCalendar(tm.Year);
}
void setTime(time_t t) {
sysTime = (uint32_t)t;
nextSyncTime = (uint32_t)t + syncInterval;
Status = timeSet;
prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
}