Merge pull request #3570 from meshtastic/local-time-display

display log and onscreen times in local timezone
This commit is contained in:
Thomas Göttgens 2024-04-08 09:18:41 +02:00 committed by GitHub
commit b14ac777f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 46 additions and 10 deletions

View File

@ -99,7 +99,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
// If we are the first message on a report, include the header // If we are the first message on a report, include the header
if (!isContinuationMessage) { if (!isContinuationMessage) {
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice); uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
if (rtc_sec > 0) { if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY; long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR; // hms += tz.tz_dsttime * SEC_PER_HOUR;

View File

@ -128,7 +128,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
#else #else
rtc.initI2C(); rtc.initI2C();
#endif #endif
tm *t = localtime(&tv->tv_sec); tm *t = gmtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
@ -142,7 +142,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
#else #else
rtc.begin(); rtc.begin();
#endif #endif
tm *t = localtime(&tv->tv_sec); tm *t = gmtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
@ -175,7 +175,15 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/ */
// horrible hack to make mktime TZ agnostic - best practise according to
// https://www.gnu.org/software/libc/manual/html_node/Broken_002ddown-Time.html
setenv("TZ", "GMT0", 1);
time_t res = mktime(&t); time_t res = mktime(&t);
if (*config.device.tzdef) {
setenv("TZ", config.device.tzdef, 1);
} else {
setenv("TZ", "UTC0", 1);
}
struct timeval tv; struct timeval tv;
tv.tv_sec = res; tv.tv_sec = res;
tv.tv_usec = 0; // time.centisecond() * (10 / 1000); tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
@ -189,14 +197,33 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
} }
} }
/**
* Returns the timezone offset in seconds.
*
* @return The timezone offset in seconds.
*/
int32_t getTZOffset()
{
time_t now;
struct tm *gmt;
now = time(NULL);
gmt = gmtime(&now);
gmt->tm_isdst = -1;
return (int16_t)difftime(now, mktime(gmt));
}
/** /**
* Returns the current time in seconds since the Unix epoch (January 1, 1970). * Returns the current time in seconds since the Unix epoch (January 1, 1970).
* *
* @return The current time in seconds since the Unix epoch. * @return The current time in seconds since the Unix epoch.
*/ */
uint32_t getTime() uint32_t getTime(bool local)
{ {
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs; if (local) {
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs + getTZOffset();
} else {
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
}
} }
/** /**
@ -205,7 +232,7 @@ uint32_t getTime()
* @param minQuality The minimum quality of the RTC time required for it to be considered valid. * @param minQuality The minimum quality of the RTC time required for it to be considered valid.
* @return The current time from the RTC if it meets the minimum quality requirement, or 0 if the time is not valid. * @return The current time from the RTC if it meets the minimum quality requirement, or 0 if the time is not valid.
*/ */
uint32_t getValidTime(RTCQuality minQuality) uint32_t getValidTime(RTCQuality minQuality, bool local)
{ {
return (currentQuality >= minQuality) ? getTime() : 0; return (currentQuality >= minQuality) ? getTime(local) : 0;
} }

View File

@ -29,10 +29,10 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv);
bool perhapsSetRTC(RTCQuality q, struct tm &t); bool perhapsSetRTC(RTCQuality q, struct tm &t);
/// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero /// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero
uint32_t getTime(); uint32_t getTime(bool local = false);
/// Return time since 1970 in secs. If quality is RTCQualityNone return zero /// Return time since 1970 in secs. If quality is RTCQualityNone return zero
uint32_t getValidTime(RTCQuality minQuality); uint32_t getValidTime(RTCQuality minQuality, bool local = false);
void readFromRTC(); void readFromRTC();

View File

@ -1896,7 +1896,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// Show uptime as days, hours, minutes OR seconds // Show uptime as days, hours, minutes OR seconds
std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds); std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds);
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice); uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
if (rtc_sec > 0) { if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY; long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR; // hms += tz.tz_dsttime * SEC_PER_HOUR;

View File

@ -663,6 +663,15 @@ void setup()
// Initialize the screen first so we can show the logo while we start up everything else. // Initialize the screen first so we can show the logo while we start up everything else.
screen = new graphics::Screen(screen_found, screen_model, screen_geometry); screen = new graphics::Screen(screen_found, screen_model, screen_geometry);
// setup TZ prior to time actions.
if (*config.device.tzdef) {
setenv("TZ", config.device.tzdef, 1);
} else {
setenv("TZ", "GMT0", 1);
}
tzset();
LOG_DEBUG("Set Timezone to %s\n", getenv("TZ"));
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
#if !MESHTASTIC_EXCLUDE_GPS #if !MESHTASTIC_EXCLUDE_GPS