kopia lustrzana https://github.com/OpenRTX/OpenRTX
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.
rodzic
f26afc42e5
commit
ce1dc202ae
|
@ -35,14 +35,13 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t hour : 5; // Hours (0-23)
|
int8_t hour; // Hours (0-23)
|
||||||
uint8_t minute : 6; // Minutes (0-59)
|
int8_t minute; // Minutes (0-59)
|
||||||
uint8_t second : 6; // Seconds (0-59)
|
int8_t second; // Seconds (0-59)
|
||||||
uint8_t day : 3; // Day of the week (1-7)
|
int8_t day; // Day of the week (1-7)
|
||||||
uint8_t date : 5; // Day of the month (1-31)
|
int8_t date; // Day of the month (1-31)
|
||||||
uint8_t month : 4; // Month (1-12)
|
int8_t month; // Month (1-12)
|
||||||
uint8_t year : 7; // Year (0-99)
|
uint8_t year; // Year (0-99)
|
||||||
uint8_t : 4; // Padding to 40 bits
|
|
||||||
}
|
}
|
||||||
datetime_t;
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,14 +51,14 @@ typedef struct
|
||||||
uint8_t contrast; // Display contrast
|
uint8_t contrast; // Display contrast
|
||||||
uint8_t sqlLevel; // Squelch level
|
uint8_t sqlLevel; // Squelch level
|
||||||
uint8_t voxLevel; // Vox 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
|
bool gps_enabled; // GPS active
|
||||||
char callsign[10]; // Plaintext callsign, for future use
|
char callsign[10]; // Plaintext callsign, for future use
|
||||||
uint8_t display_timer : 4, // Standby timer
|
uint8_t display_timer : 4, // Standby timer
|
||||||
not_in_use : 4;
|
_ununsed : 4;
|
||||||
uint8_t vpLevel : 3,
|
uint8_t vpLevel : 3, // Voice prompt level
|
||||||
vpPhoneticSpell : 1,
|
vpPhoneticSpell : 1, // Phonetic spell enabled
|
||||||
vpReserved : 4; // reserved for voice rate on the fly.
|
_reserved : 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
__attribute__((packed)) settings_t;
|
__attribute__((packed)) settings_t;
|
||||||
|
@ -78,10 +78,10 @@ static const settings_t default_settings =
|
||||||
false, // GPS enabled
|
false, // GPS enabled
|
||||||
"", // Empty callsign
|
"", // Empty callsign
|
||||||
TIMER_30S, // 30 seconds
|
TIMER_30S, // 30 seconds
|
||||||
0, // not in use
|
0, // not used
|
||||||
0, // vpOff,
|
0, // Voice prompts off
|
||||||
0, // phonetic spell off,
|
0, // Phonetic spell off
|
||||||
0 // not in use.
|
0 // not used
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SETTINGS_H */
|
#endif /* SETTINGS_H */
|
||||||
|
|
|
@ -19,26 +19,42 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <datetime.h>
|
#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 utcToLocalTime(const datetime_t utc_time, const int8_t timezone)
|
||||||
{
|
{
|
||||||
datetime_t local_time = utc_time;
|
datetime_t local_time = utc_time;
|
||||||
|
|
||||||
if(local_time.hour + timezone >= 24)
|
local_time.hour += (timezone / 2);
|
||||||
{
|
local_time.minute += (timezone % 2) * 30;
|
||||||
local_time.hour = local_time.hour - 24 + timezone;
|
realignTimeInfo(&local_time);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 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;
|
datetime_t utc_time = local_time;
|
||||||
|
|
||||||
if(utc_time.hour - timezone >= 24)
|
utc_time.minute -= (timezone % 2) * 30;
|
||||||
{
|
utc_time.hour -= (timezone / 2);
|
||||||
utc_time.hour = utc_time.hour - 24 - timezone;
|
realignTimeInfo(&utc_time);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1893,10 +1893,10 @@ void ui_updateFSM(bool *sync_rtx)
|
||||||
state.gps_set_time);
|
state.gps_set_time);
|
||||||
break;
|
break;
|
||||||
case G_TIMEZONE:
|
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)
|
msg.keys & KNOB_LEFT)
|
||||||
state.settings.utc_timezone -= 1;
|
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)
|
msg.keys & KNOB_RIGHT)
|
||||||
state.settings.utc_timezone += 1;
|
state.settings.utc_timezone += 1;
|
||||||
vp_announceSettingsInt(¤tLanguage->UTCTimeZone,
|
vp_announceSettingsInt(¤tLanguage->UTCTimeZone,
|
||||||
|
|
|
@ -296,17 +296,34 @@ int _ui_getSettingsGPSValueName(char *buf, uint8_t max_len, uint8_t index)
|
||||||
switch(index)
|
switch(index)
|
||||||
{
|
{
|
||||||
case G_ENABLED:
|
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;
|
break;
|
||||||
case G_SET_TIME:
|
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;
|
break;
|
||||||
case G_TIMEZONE:
|
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)
|
if(last_state.settings.utc_timezone > 0)
|
||||||
snprintf(buf, max_len, "+%d", last_state.settings.utc_timezone);
|
{
|
||||||
else
|
sign = '+';
|
||||||
snprintf(buf, max_len, "%d", last_state.settings.utc_timezone);
|
}
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Ładowanie…
Reference in New Issue