You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
4.3 KiB
176 lines
4.3 KiB
2 years ago
|
#ifdef EEZ_PLATFORM_STM32
|
||
|
#include "main.h"
|
||
|
//#include "rtc.h"
|
||
|
#endif
|
||
|
|
||
|
#if defined(EEZ_PLATFORM_SIMULATOR)
|
||
|
#include <stdio.h>
|
||
|
#include <time.h>
|
||
|
#endif
|
||
|
|
||
|
#include "date_time.h"
|
||
|
|
||
|
namespace date_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 SECONDS_PER_MINUTE 60UL
|
||
|
#define SECONDS_PER_HOUR (SECONDS_PER_MINUTE * 60)
|
||
|
#define SECONDS_PER_DAY (SECONDS_PER_HOUR * 24)
|
||
|
|
||
|
// 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 };
|
||
|
|
||
|
#if defined(EEZ_PLATFORM_SIMULATOR)
|
||
|
static uint32_t g_offset;
|
||
|
#endif
|
||
|
|
||
|
DateTime g_dateTime;
|
||
|
|
||
|
uint32_t makeTime(int year, int month, int day, int hour, int minute, int second) {
|
||
|
// seconds from 1970 till 1 jan 00:00:00 of the given year
|
||
|
year -= 1970;
|
||
|
|
||
|
uint32_t seconds = year * 365 * SECONDS_PER_DAY;
|
||
|
|
||
|
for (int i = 0; i < year; i++) {
|
||
|
if (LEAP_YEAR(i)) {
|
||
|
seconds += SECONDS_PER_DAY; // add extra days for leap years
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// add days for this year, months start from 1
|
||
|
for (int i = 1; i < month; i++) {
|
||
|
if ((i == 2) && LEAP_YEAR(year)) {
|
||
|
seconds += SECONDS_PER_DAY * 29;
|
||
|
}
|
||
|
else {
|
||
|
seconds += SECONDS_PER_DAY * monthDays[i - 1]; // monthDay array starts from 0
|
||
|
}
|
||
|
}
|
||
|
seconds += (day - 1) * SECONDS_PER_DAY;
|
||
|
seconds += hour * SECONDS_PER_HOUR;
|
||
|
seconds += minute * SECONDS_PER_MINUTE;
|
||
|
seconds += second;
|
||
|
|
||
|
return seconds;
|
||
|
}
|
||
|
|
||
|
void breakTime(uint32_t time, int &resultYear, int &resultMonth, int &resultDay, int &resultHour,
|
||
|
int &resultMinute, int &resultSecond) {
|
||
|
// break the given time_t into time components
|
||
|
uint8_t year;
|
||
|
uint8_t month, monthLength;
|
||
|
uint32_t days;
|
||
|
|
||
|
resultSecond = time % 60;
|
||
|
time /= 60; // now it is minutes
|
||
|
|
||
|
resultMinute = time % 60;
|
||
|
time /= 60; // now it is hours
|
||
|
|
||
|
resultHour = time % 24;
|
||
|
time /= 24; // now it is days
|
||
|
|
||
|
year = 0;
|
||
|
days = 0;
|
||
|
while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
|
||
|
year++;
|
||
|
}
|
||
|
resultYear = year + 1970; // 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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
resultMonth = month + 1; // jan is month 1
|
||
|
resultDay = time + 1; // day of month
|
||
|
}
|
||
|
|
||
|
#if defined(EEZ_PLATFORM_SIMULATOR)
|
||
|
uint32_t nowUtc() {
|
||
|
time_t now_time_t = time(0);
|
||
|
struct tm *now_tm = gmtime(&now_time_t);
|
||
|
return makeTime(1900 + now_tm->tm_year, now_tm->tm_mon + 1, now_tm->tm_mday,
|
||
|
now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
bool readTime(uint8_t &hour, uint8_t &minute, uint8_t &second, uint8_t &subSeconds) {
|
||
|
#if defined(EEZ_PLATFORM_STM32)
|
||
|
// RTC_TimeTypeDef time;
|
||
|
// HAL_RTC_GetTime(&hrtc, &time, FORMAT_BIN);
|
||
|
//
|
||
|
// second = time.Seconds;
|
||
|
// minute = time.Minutes;
|
||
|
// hour = time.Hours;
|
||
|
// subSeconds = time.SubSeconds;
|
||
|
#endif
|
||
|
|
||
|
#if defined(EEZ_PLATFORM_SIMULATOR)
|
||
|
int year_, month_, day_, hour_, minute_, second_;
|
||
|
breakTime(g_offset + nowUtc(), year_, month_, day_, hour_, minute_, second_);
|
||
|
|
||
|
hour = uint8_t(hour_);
|
||
|
minute = uint8_t(minute_);
|
||
|
second = uint8_t(second_);
|
||
|
subSeconds = 0;
|
||
|
#endif
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool readDate(uint8_t &year, uint8_t &month, uint8_t &day) {
|
||
|
#if defined(EEZ_PLATFORM_STM32)
|
||
|
// RTC_DateTypeDef date;
|
||
|
// HAL_RTC_GetDate(&hrtc, &date, FORMAT_BIN);
|
||
|
//
|
||
|
// day = date.Date;
|
||
|
// month = date.Month;
|
||
|
// year = date.Year;
|
||
|
#endif
|
||
|
|
||
|
#if defined(EEZ_PLATFORM_SIMULATOR)
|
||
|
int year_, month_, day_, hour_, minute_, second_;
|
||
|
breakTime(g_offset + nowUtc(), year_, month_, day_, hour_, minute_, second_);
|
||
|
|
||
|
year = uint8_t(year_ - 2000);
|
||
|
month = uint8_t(month_);
|
||
|
day = uint8_t(day_);
|
||
|
#endif
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void tick() {
|
||
|
readTime(g_dateTime.hour, g_dateTime.minute, g_dateTime.second, g_dateTime.subSecond);
|
||
|
readDate(g_dateTime.year, g_dateTime.month, g_dateTime.day);
|
||
|
}
|
||
|
|
||
|
} // date_time
|