TmeLib tests
It is now possible to use the internal vscode test tool with the cmake plugin to test timelib
This commit is contained in:
165
tests/time.cpp
Normal file
165
tests/time.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "time.hpp"
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
* @fn uint8_t IsDST(ts)
|
||||
* @brief
|
||||
*
|
||||
* @param tm
|
||||
* @return
|
||||
*/
|
||||
uint8_t IsDST(ts *tm)
|
||||
{
|
||||
uint8_t nextSunday;
|
||||
uint16_t y, m, d;
|
||||
//number of days of each month
|
||||
int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
// January, february, and december are out.
|
||||
if (tm->Month < 3 || tm->Month > 10)
|
||||
{
|
||||
tm->IsDST = 0;
|
||||
return tm->IsDST;
|
||||
}
|
||||
// April to september are in
|
||||
if (tm->Month > 3 && tm->Month < 10)
|
||||
{
|
||||
tm->IsDST = 1;
|
||||
return tm->IsDST;
|
||||
}
|
||||
|
||||
m = tm->Month;
|
||||
y = tm->Year + 1970;
|
||||
days[1] -= (y % 4) || (!(y % 100) && (y % 400));
|
||||
d = days[m - 1];
|
||||
|
||||
/* dow is in normal format*/
|
||||
nextSunday = days[m-1] - ((d += m < 3 ? y-- : y - 2, 23*m/9 + d + 4 + y/4- y/100 + y/400)%7);
|
||||
// Start: Last Sunday in March
|
||||
if (tm->Month == 3)
|
||||
{
|
||||
tm->IsDST = tm->Day >= nextSunday ? (tm->Day == nextSunday ? (tm->Hour >= 0) : 1) : 0;
|
||||
return tm->IsDST;
|
||||
}
|
||||
|
||||
// End: Last Sunday in October
|
||||
tm->IsDST = tm->Day >= nextSunday ? (tm->Day == nextSunday ? (tm->Hour < 0) : 0) : 1;
|
||||
return tm->IsDST;
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
/* functions to convert to and from system time */
|
||||
/* These are for interfacing with time services and are not normally needed in a sketch */
|
||||
|
||||
void breakTime(uint32_t timeInput, ts *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;
|
||||
unsigned long days;
|
||||
|
||||
tm->unixtime = timeInput;
|
||||
tm->Second = timeInput % 60;
|
||||
timeInput /= 60; // now it is minutes
|
||||
tm->Minute = timeInput % 60;
|
||||
timeInput /= 60; // now it is hours
|
||||
tm->Hour = timeInput % 24;
|
||||
timeInput /= 24; // now it is days
|
||||
tm->Wday = ((timeInput + 4) % 7) + 1; // Sunday is day 1
|
||||
|
||||
year = 0;
|
||||
days = 0;
|
||||
while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= timeInput)
|
||||
{
|
||||
year++;
|
||||
}
|
||||
tm->Year = year; // year is offset from 1970
|
||||
|
||||
days -= LEAP_YEAR(year) ? 366 : 365;
|
||||
timeInput -= 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 (timeInput >= monthLength)
|
||||
{
|
||||
timeInput -= monthLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
tm->Month = month + 1; // jan is month 1
|
||||
tm->Day = timeInput + 1; // day of month
|
||||
|
||||
IsDST(tm);
|
||||
}
|
||||
|
||||
uint32_t makeTime(ts *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*(NUMBEROFSECONDSPERDAY * 365);
|
||||
for (i = 0; i < tm->Year; i++) {
|
||||
if (LEAP_YEAR(i)) {
|
||||
seconds += NUMBEROFSECONDSPERDAY; // 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 += NUMBEROFSECONDSPERDAY * 29;
|
||||
} else {
|
||||
seconds += NUMBEROFSECONDSPERDAY * monthDays[i-1]; //monthDay array starts from 0
|
||||
}
|
||||
}
|
||||
seconds+= (tm->Day-1) * NUMBEROFSECONDSPERDAY;
|
||||
seconds+= tm->Hour * NUMBEROFSECONDSPERHOUR;
|
||||
seconds+= tm->Minute * NUMBEROFSECONDSPERMINUTE;
|
||||
seconds+= tm->Second;
|
||||
|
||||
tm->unixtime = seconds;
|
||||
return seconds;
|
||||
}
|
||||
|
||||
void toTimeZone(ts *utc, ts* local, int8_t timeZone)
|
||||
{
|
||||
// convert UTC time to local time
|
||||
// timeZone is in hours
|
||||
// local is a pointer to a tm structure
|
||||
// this function is not reentrant
|
||||
|
||||
uint32_t localTime = makeTime(utc) + timeZone * NUMBEROFSECONDSPERHOUR;
|
||||
breakTime(localTime, local);
|
||||
}
|
||||
Reference in New Issue
Block a user