Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shortcut in breakTime when referring to same day #94

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 79 additions & 75 deletions Time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,17 @@

#include "TimeLib.h"

static tmElements_t tm; // a cache of time elements
// Convert days since epoch to week day. Sunday is day 1.
#define DAYS_TO_WDAY(x) (((x) + 4) % 7) + 1

static tmElements_t cacheElements; // 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

void refreshCache(time_t t) {
if (t != cacheTime) {
breakTime(t, tm);
cacheTime = t;
breakTime(t, cacheElements);
cacheTime = t;
}
}

Expand All @@ -52,7 +55,7 @@ int hour() { // the hour now

int hour(time_t t) { // the hour for the given time
refreshCache(t);
return tm.Hour;
return cacheElements.Hour;
}

int hourFormat12() { // the hour now in 12 hour format
Expand All @@ -61,12 +64,12 @@ int hourFormat12() { // the hour now in 12 hour format

int hourFormat12(time_t t) { // the hour for the given time in 12 hour format
refreshCache(t);
if( tm.Hour == 0 )
if( cacheElements.Hour == 0 )
return 12; // 12 midnight
else if( tm.Hour > 12)
return tm.Hour - 12 ;
else if( cacheElements.Hour > 12)
return cacheElements.Hour - 12 ;
else
return tm.Hour ;
return cacheElements.Hour ;
}

uint8_t isAM() { // returns true if time now is AM
Expand All @@ -91,7 +94,7 @@ int minute() {

int minute(time_t t) { // the minute for the given time
refreshCache(t);
return tm.Minute;
return cacheElements.Minute;
}

int second() {
Expand All @@ -100,7 +103,7 @@ int second() {

int second(time_t t) { // the second for the given time
refreshCache(t);
return tm.Second;
return cacheElements.Second;
}

int day(){
Expand All @@ -109,16 +112,16 @@ int day(){

int day(time_t t) { // the day for the given time (0-6)
refreshCache(t);
return tm.Day;
return cacheElements.Day;
}

int weekday() { // Sunday is day 1
return weekday(now());
return weekday(now());
}

int weekday(time_t t) {
refreshCache(t);
return tm.Wday;
return cacheElements.Wday;
}

int month(){
Expand All @@ -127,7 +130,7 @@ int month(){

int month(time_t t) { // the month for the given time
refreshCache(t);
return tm.Month;
return cacheElements.Month;
}

int year() { // as in Processing, the full four digit year: (2009, 2010 etc)
Expand All @@ -136,7 +139,7 @@ int year() { // as in Processing, the full four digit year: (2009, 2010 etc)

int year(time_t t) { // the year for the given time
refreshCache(t);
return tmYearToCalendar(tm.Year);
return tmYearToCalendar(cacheElements.Year);
}

/*============================================================================*/
Expand All @@ -145,60 +148,59 @@ int year(time_t t) { // the year for the given time

// leap year calulator expects year argument as years offset from 1970
#define LEAP_YEAR(Y) ( ((1970+(Y))>0) && !((1970+(Y))%4) && ( ((1970+(Y))%100) || !((1970+(Y))%400) ) )
#define daysInYear(year) ((time_t) (LEAP_YEAR(year) ? 366 : 365))

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

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

void breakTime(time_t timeInput, tmElements_t &tm){
void breakTime(time_t time, 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;
uint8_t period;
time_t length;

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++;
time /= 24; // now it is days since 1 Jan 1970

// if the number of days since epoch matches cacheTime, then can take date
// elements from cacheElements and avoid expensive calculation.
if (time == (cacheTime / SECS_PER_DAY)) {
if (&tm != &cacheElements) { // check whether tm is actually cacheElements
tm.Wday = cacheElements.Wday;
tm.Day = cacheElements.Day;
tm.Month = cacheElements.Month;
tm.Year = cacheElements.Year;
}
return;
}
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

tm.Wday = DAYS_TO_WDAY(time);

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;
}
period = 0;
while (time >= (length = daysInYear(period)))
{
time -= length;
period++;
}
tm.Year = period; // year is offset from 1970
// time is now days since 1 Jan of the year

bool leap_year = LEAP_YEAR(period);
period = 0;
while (period < 12 && time >= (length = monthDays[period] + (leap_year && period==1)))
{
time -= length;
period++;
}
tm.Month = month + 1; // jan is month 1
tm.Day = time + 1; // day of month
tm.Month = period + 1; // jan is month 1
// time is now days since the 1st day of the month

tm.Day = time + 1; // day of month
}

time_t makeTime(const tmElements_t &tm){
Expand All @@ -210,7 +212,7 @@ time_t makeTime(const tmElements_t &tm){
uint32_t seconds;

// seconds from 1970 till 1 jan 00:00:00 of the given year
seconds= tm.Year*(SECS_PER_DAY * 365);
seconds = SECS_PER_DAY * (365 * tm.Year);
for (i = 0; i < tm.Year; i++) {
if (LEAP_YEAR(i)) {
seconds += SECS_PER_DAY; // add extra days for leap years
Expand All @@ -234,9 +236,9 @@ time_t makeTime(const tmElements_t &tm){
/*=====================================================*/
/* Low level system time functions */

static uint32_t sysTime = 0;
static time_t sysTime = 0;
static uint32_t prevMillis = 0;
static uint32_t nextSyncTime = 0;
static time_t nextSyncTime = 0;
static timeStatus_t Status = timeNotSet;

getExternalTime getTimePtr; // pointer to external sync function
Expand Down Expand Up @@ -268,7 +270,7 @@ time_t now() {
}
}
}
return (time_t)sysTime;
return sysTime;
}

void setTime(time_t t) {
Expand All @@ -277,26 +279,28 @@ void setTime(time_t t) {
sysUnsyncedTime = t; // store the time of the first call to set a valid Time
#endif

sysTime = (uint32_t)t;
nextSyncTime = (uint32_t)t + syncInterval;
sysTime = t;
nextSyncTime = t + (time_t) syncInterval;
Status = timeSet;
prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
}

void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
// year can be given as full four digit year or two digts (2010 or 10 for 2010);
//it is converted to years since 1970
if( yr > 99)
yr = yr - 1970;
void setTime(int hr, int min, int sec, int dy, int mnth, int yr) {
// year can be given as full four digit year or two digts (2010 or 10 for 2010);
// it is converted to years since 1970
if (yr > 99)
yr = CalendarYrToTm(yr);
else
yr += 30;
tm.Year = yr;
tm.Month = mnth;
tm.Day = dy;
tm.Hour = hr;
tm.Minute = min;
tm.Second = sec;
setTime(makeTime(tm));
yr = tmYearToY2k(yr);
cacheElements.Year = yr;
cacheElements.Month = mnth;
cacheElements.Day = dy;
cacheElements.Hour = hr;
cacheElements.Minute = min;
cacheElements.Second = sec;
cacheTime = makeTime(cacheElements);
cacheElements.Wday = DAYS_TO_WDAY(cacheTime / SECS_PER_DAY);
setTime(cacheTime);
}

void adjustTime(long adjustment) {
Expand All @@ -309,7 +313,7 @@ timeStatus_t timeStatus() {
return Status;
}

void setSyncProvider( getExternalTime getTimeFunction){
void setSyncProvider(getExternalTime getTimeFunction){
getTimePtr = getTimeFunction;
nextSyncTime = sysTime;
now(); // this will sync the clock
Expand Down