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
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(¤tLanguage->UTCTimeZone,
|
||||
|
|
|
@ -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;
|
||||
|
|
Ładowanie…
Reference in New Issue