Added support for half-hour timezones, moved datetime_t struct fields from bitfields to full 8-bit variables, added function to adjust the off-range fields of a datetime_t struct.

md1702
Silvano Seva 2022-10-31 11:41:54 +01:00
rodzic f26afc42e5
commit ce1dc202ae
5 zmienionych plików z 177 dodań i 54 usunięć

Wyświetl plik

@ -35,14 +35,13 @@ extern "C" {
*/
typedef struct
{
uint8_t hour : 5; // Hours (0-23)
uint8_t minute : 6; // Minutes (0-59)
uint8_t second : 6; // Seconds (0-59)
uint8_t day : 3; // Day of the week (1-7)
uint8_t date : 5; // Day of the month (1-31)
uint8_t month : 4; // Month (1-12)
uint8_t year : 7; // Year (0-99)
uint8_t : 4; // Padding to 40 bits
int8_t hour; // Hours (0-23)
int8_t minute; // Minutes (0-59)
int8_t second; // Seconds (0-59)
int8_t day; // Day of the week (1-7)
int8_t date; // Day of the month (1-31)
int8_t month; // Month (1-12)
uint8_t year; // Year (0-99)
}
datetime_t;
@ -64,6 +63,14 @@ datetime_t utcToLocalTime(const datetime_t utc_time, const int8_t timezone);
*/
datetime_t localTimeToUtc(const datetime_t local_time, const int8_t timezone);
/**
* Adjust the values of the members of datetime_t if they are off-range or if
* they have values that do not match the date described by the other members.
*
* @param time: pointer to a datetime_t struct.
*/
void realignTimeInfo(datetime_t *time);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -51,14 +51,14 @@ typedef struct
uint8_t contrast; // Display contrast
uint8_t sqlLevel; // Squelch level
uint8_t voxLevel; // Vox level
int8_t utc_timezone; // Timezone
int8_t utc_timezone; // Timezone, in units of half hours
bool gps_enabled; // GPS active
char callsign[10]; // Plaintext callsign, for future use
uint8_t display_timer : 4, // Standby timer
not_in_use : 4;
uint8_t vpLevel : 3,
vpPhoneticSpell : 1,
vpReserved : 4; // reserved for voice rate on the fly.
uint8_t display_timer : 4, // Standby timer
_ununsed : 4;
uint8_t vpLevel : 3, // Voice prompt level
vpPhoneticSpell : 1, // Phonetic spell enabled
_reserved : 4;
}
__attribute__((packed)) settings_t;
@ -78,10 +78,10 @@ static const settings_t default_settings =
false, // GPS enabled
"", // Empty callsign
TIMER_30S, // 30 seconds
0, // not in use
0, // vpOff,
0, // phonetic spell off,
0 // not in use.
0, // not used
0, // Voice prompts off
0, // Phonetic spell off
0 // not used
};
#endif /* SETTINGS_H */

Wyświetl plik

@ -19,26 +19,42 @@
***************************************************************************/
#include <datetime.h>
#include <stdlib.h>
#include <time.h>
static const int DAYS_IN_MONTH[12] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
#define _DAYS_IN_MONTH(x) ((x == 2) ? days_in_feb : DAYS_IN_MONTH[x - 1])
/**
* \internal
* Return the number of days in a year by checking wheter the current year is
* a leap one or not.
*
* @param year: current year, ranging from 0 to 99.
* @return number of days in the year.
*/
static inline uint16_t daysInYear(uint16_t year)
{
year += 2000;
if( ((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0)))
{
return 366;
}
return 365;
}
datetime_t utcToLocalTime(const datetime_t utc_time, const int8_t timezone)
{
datetime_t local_time = utc_time;
if(local_time.hour + timezone >= 24)
{
local_time.hour = local_time.hour - 24 + timezone;
local_time.date += 1;
}
else if(local_time.hour + timezone < 0)
{
local_time.hour = local_time.hour + 24 + timezone;
local_time.date -= 1;
}
else
{
local_time.hour += timezone;
}
local_time.hour += (timezone / 2);
local_time.minute += (timezone % 2) * 30;
realignTimeInfo(&local_time);
return local_time;
}
@ -47,20 +63,103 @@ datetime_t localTimeToUtc(const datetime_t local_time, const int8_t timezone)
{
datetime_t utc_time = local_time;
if(utc_time.hour - timezone >= 24)
{
utc_time.hour = utc_time.hour - 24 - timezone;
utc_time.date += 1;
}
else if(utc_time.hour - timezone < 0)
{
utc_time.hour = utc_time.hour + 24 - timezone;
utc_time.date -= 1;
}
else
{
utc_time.hour -= timezone;
}
utc_time.minute -= (timezone % 2) * 30;
utc_time.hour -= (timezone / 2);
realignTimeInfo(&utc_time);
return utc_time;
}
/*
* Function borrowed from newlib implementation of mktime, see
* https://github.com/bminor/newlib/blob/master/newlib/libc/time/mktime.c
*
* Slightly modified to remove the _DAYS_IN_YEAR macro and to handle month
* with range 1-12 instead of 0-11.
*/
void realignTimeInfo(datetime_t *time)
{
div_t res;
int days_in_feb = 28;
if((time->second < 0) || (time->second > 59))
{
res = div(time->second, 60);
time->minute += res.quot;
if ((time->second = res.rem) < 0)
{
time->second += 60;
time->minute -= 1;
}
}
if((time->minute < 0) || (time->minute > 59))
{
res = div(time->minute, 60);
time->hour += res.quot;
if((time->minute = res.rem) < 0)
{
time->minute += 60;
time->hour -= 1;
}
}
if((time->hour < 0) || (time->hour > 23))
{
res = div(time->hour, 24);
time->date += res.quot;
if((time->hour = res.rem) < 0)
{
time->hour += 24;
time->date -= 1;
}
}
if((time->month < 0) || (time->month > 12))
{
res = div (time->month, 12);
time->year += res.quot;
if((time->month = res.rem) < 0)
{
time->month += 12;
time->year -= 1;
}
}
if(daysInYear(time->year) == 366)
days_in_feb = 29;
if(time->date <= 0)
{
while(time->date <= 0)
{
time->month -= 1;
if(time->month == -1)
{
time->year -= 1;
time->month = 12;
days_in_feb = ((daysInYear(time->year) == 366) ? 29 : 28);
}
time->date += _DAYS_IN_MONTH (time->month);
}
}
else
{
while(time->date > _DAYS_IN_MONTH (time->month))
{
time->date -= _DAYS_IN_MONTH (time->month);
time->month += 1;
if (time->month > 12)
{
time->year += 1;
time->month = 1;
days_in_feb = ((daysInYear (time->year) == 366) ? 29 : 28);
}
}
}
}

Wyświetl plik

@ -1893,10 +1893,10 @@ void ui_updateFSM(bool *sync_rtx)
state.gps_set_time);
break;
case G_TIMEZONE:
if(msg.keys & KEY_LEFT || msg.keys & KEY_UP ||
if(msg.keys & KEY_LEFT || msg.keys & KEY_DOWN ||
msg.keys & KNOB_LEFT)
state.settings.utc_timezone -= 1;
else if(msg.keys & KEY_RIGHT || msg.keys & KEY_DOWN ||
else if(msg.keys & KEY_RIGHT || msg.keys & KEY_UP ||
msg.keys & KNOB_RIGHT)
state.settings.utc_timezone += 1;
vp_announceSettingsInt(&currentLanguage->UTCTimeZone,

Wyświetl plik

@ -296,17 +296,34 @@ int _ui_getSettingsGPSValueName(char *buf, uint8_t max_len, uint8_t index)
switch(index)
{
case G_ENABLED:
snprintf(buf, max_len, "%s", (last_state.settings.gps_enabled) ? currentLanguage->on : currentLanguage->off);
snprintf(buf, max_len, "%s", (last_state.settings.gps_enabled) ?
currentLanguage->on :
currentLanguage->off);
break;
case G_SET_TIME:
snprintf(buf, max_len, "%s", (last_state.gps_set_time) ? currentLanguage->on : currentLanguage->off);
snprintf(buf, max_len, "%s", (last_state.gps_set_time) ?
currentLanguage->on :
currentLanguage->off);
break;
case G_TIMEZONE:
// Add + prefix to positive numbers
{
int8_t tz_hr = (last_state.settings.utc_timezone / 2);
int8_t tz_mn = (last_state.settings.utc_timezone % 2) * 5;
char sign = ' ';
if(last_state.settings.utc_timezone > 0)
snprintf(buf, max_len, "+%d", last_state.settings.utc_timezone);
else
snprintf(buf, max_len, "%d", last_state.settings.utc_timezone);
{
sign = '+';
}
else if(last_state.settings.utc_timezone < 0)
{
sign = '-';
tz_hr *= (-1);
tz_mn *= (-1);
}
snprintf(buf, max_len, "%c%d.%d", sign, tz_hr, tz_mn);
}
break;
}
return 0;