mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-23 14:29:23 -05:00
When setting Time & Date indicate if in DST range (#1851)
This commit is contained in:
parent
5ea1bff1e6
commit
61d9c051de
@ -81,6 +81,7 @@ SetDateTimeView::SetDateTimeView(
|
||||
&field_second,
|
||||
&text_weekday,
|
||||
&text_day_of_year,
|
||||
&text_in_dst_range,
|
||||
&checkbox_dst_enable,
|
||||
&options_dst_start_which,
|
||||
&options_dst_start_weekday,
|
||||
@ -100,18 +101,25 @@ SetDateTimeView::SetDateTimeView(
|
||||
options_dst_start_month.set_options(month_options);
|
||||
options_dst_end_month.set_options(month_options);
|
||||
|
||||
const auto dst_changed_fn = [this](size_t, uint32_t) {
|
||||
handle_date_field_update();
|
||||
};
|
||||
|
||||
const auto date_changed_fn = [this](int32_t) {
|
||||
auto weekday = rtc_time::day_of_week(field_year.value(), field_month.value(), field_day.value());
|
||||
auto doy = rtc_time::day_of_year(field_year.value(), field_month.value(), field_day.value());
|
||||
bool valid_date = (field_day.value() <= rtc_time::days_per_month(field_year.value(), field_month.value()));
|
||||
text_weekday.set(valid_date ? weekday_options[weekday].first : "-");
|
||||
text_day_of_year.set(valid_date ? to_string_dec_uint(doy, 3) : "-");
|
||||
handle_date_field_update();
|
||||
};
|
||||
|
||||
field_year.on_change = date_changed_fn;
|
||||
field_month.on_change = date_changed_fn;
|
||||
field_day.on_change = date_changed_fn;
|
||||
|
||||
options_dst_start_which.on_change = dst_changed_fn;
|
||||
options_dst_start_weekday.on_change = dst_changed_fn;
|
||||
options_dst_start_month.on_change = dst_changed_fn;
|
||||
options_dst_end_which.on_change = dst_changed_fn;
|
||||
options_dst_end_weekday.on_change = dst_changed_fn;
|
||||
options_dst_end_month.on_change = dst_changed_fn;
|
||||
|
||||
rtc::RTC datetime;
|
||||
rtc_time::now(datetime);
|
||||
SetDateTimeModel model{
|
||||
@ -146,6 +154,17 @@ void SetDateTimeView::form_init(const SetDateTimeModel& model) {
|
||||
}
|
||||
|
||||
SetDateTimeModel SetDateTimeView::form_collect() {
|
||||
return {
|
||||
.year = static_cast<uint16_t>(field_year.value()),
|
||||
.month = static_cast<uint8_t>(field_month.value()),
|
||||
.day = static_cast<uint8_t>(field_day.value()),
|
||||
.hour = static_cast<uint8_t>(field_hour.value()),
|
||||
.minute = static_cast<uint8_t>(field_minute.value()),
|
||||
.second = static_cast<uint8_t>(field_second.value()),
|
||||
.dst = dst_collect()};
|
||||
}
|
||||
|
||||
pmem::dst_config_t SetDateTimeView::dst_collect() {
|
||||
pmem::dst_config_t dst;
|
||||
dst.b.dst_enabled = static_cast<uint8_t>(checkbox_dst_enable.value());
|
||||
dst.b.start_which = static_cast<uint8_t>(options_dst_start_which.selected_index_value());
|
||||
@ -154,14 +173,16 @@ SetDateTimeModel SetDateTimeView::form_collect() {
|
||||
dst.b.end_which = static_cast<uint8_t>(options_dst_end_which.selected_index_value());
|
||||
dst.b.end_weekday = static_cast<uint8_t>(options_dst_end_weekday.selected_index_value());
|
||||
dst.b.end_month = static_cast<uint8_t>(options_dst_end_month.selected_index_value());
|
||||
return {
|
||||
.year = static_cast<uint16_t>(field_year.value()),
|
||||
.month = static_cast<uint8_t>(field_month.value()),
|
||||
.day = static_cast<uint8_t>(field_day.value()),
|
||||
.hour = static_cast<uint8_t>(field_hour.value()),
|
||||
.minute = static_cast<uint8_t>(field_minute.value()),
|
||||
.second = static_cast<uint8_t>(field_second.value()),
|
||||
.dst = dst};
|
||||
return dst;
|
||||
}
|
||||
|
||||
void SetDateTimeView::handle_date_field_update() {
|
||||
auto weekday = rtc_time::day_of_week(field_year.value(), field_month.value(), field_day.value());
|
||||
auto doy = rtc_time::day_of_year(field_year.value(), field_month.value(), field_day.value());
|
||||
bool valid_date = (field_day.value() <= rtc_time::days_per_month(field_year.value(), field_month.value()));
|
||||
text_weekday.set(valid_date ? weekday_options[weekday].first : "-");
|
||||
text_day_of_year.set(valid_date ? to_string_dec_uint(doy, 3) : "-");
|
||||
text_in_dst_range.set(checkbox_dst_enable.value() && rtc_time::dst_test_date_range(field_year.value(), doy, dst_collect()) ? "DST" : "");
|
||||
}
|
||||
|
||||
/* SetRadioView ******************************************/
|
||||
|
@ -126,6 +126,9 @@ class SetDateTimeView : public View {
|
||||
Text text_day_of_year{
|
||||
{26 * 8, 6 * 16, 3 * 8, 16},
|
||||
""};
|
||||
Text text_in_dst_range{
|
||||
{17 * 8, 7 * 16, 3 * 8, 16},
|
||||
""};
|
||||
|
||||
Checkbox checkbox_dst_enable{
|
||||
{2 * 8, 9 * 16},
|
||||
@ -171,6 +174,8 @@ class SetDateTimeView : public View {
|
||||
|
||||
void form_init(const SetDateTimeModel& model);
|
||||
SetDateTimeModel form_collect();
|
||||
portapack::persistent_memory::dst_config_t dst_collect();
|
||||
void handle_date_field_update();
|
||||
};
|
||||
|
||||
struct SetFrequencyCorrectionModel {
|
||||
|
@ -21,9 +21,10 @@
|
||||
*/
|
||||
|
||||
#include "rtc_time.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
using namespace lpc43xx;
|
||||
using namespace portapack;
|
||||
|
||||
namespace pmem = portapack::persistent_memory;
|
||||
|
||||
namespace rtc_time {
|
||||
@ -77,8 +78,10 @@ rtc::RTC dst_adjust_returned_time(rtc::RTC& datetime) {
|
||||
if (doy != dst_current_doy) {
|
||||
if (datetime.year() != dst_current_year)
|
||||
dst_update_date_range(datetime.year(), doy);
|
||||
else
|
||||
dst_check_date_range(doy);
|
||||
else {
|
||||
dst_current_doy = doy;
|
||||
dst_in_range = dst_check_date_range(doy, dst_start_doy, dst_end_doy);
|
||||
}
|
||||
}
|
||||
|
||||
// Not in DST date range
|
||||
@ -105,15 +108,13 @@ rtc::RTC dst_adjust_returned_time(rtc::RTC& datetime) {
|
||||
}
|
||||
|
||||
// Check if current date is within the DST range (called when date changes)
|
||||
void dst_check_date_range(uint16_t doy) {
|
||||
dst_current_doy = doy;
|
||||
|
||||
bool dst_check_date_range(uint16_t doy, uint16_t start_doy, uint16_t end_doy) {
|
||||
// Check if date is within DST range
|
||||
// (note that dates are reversed in Southern hemisphere because Summer starts in December)
|
||||
if (dst_start_doy <= dst_end_doy)
|
||||
dst_in_range = ((doy >= dst_start_doy) && (doy < dst_end_doy));
|
||||
if (start_doy <= end_doy)
|
||||
return ((doy >= start_doy) && (doy < end_doy));
|
||||
else
|
||||
dst_in_range = ((doy >= dst_start_doy) || (doy < dst_end_doy));
|
||||
return ((doy >= start_doy) || (doy < end_doy));
|
||||
}
|
||||
|
||||
// Update DST parameters (called at power-up, when year changes, or DST settings are changed)
|
||||
@ -125,12 +126,20 @@ void dst_update_date_range(uint16_t year, uint16_t doy) {
|
||||
dst_start_doy = day_of_year_of_nth_weekday(dst_current_year, dst.b.start_month, dst.b.start_which, dst.b.start_weekday);
|
||||
dst_end_doy = day_of_year_of_nth_weekday(dst_current_year, dst.b.end_month, dst.b.end_which, dst.b.end_weekday);
|
||||
|
||||
dst_check_date_range(doy);
|
||||
dst_current_doy = doy;
|
||||
dst_in_range = dst_check_date_range(doy, dst_start_doy, dst_end_doy);
|
||||
} else {
|
||||
dst_in_range = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test date range for display purposes only when setting Time
|
||||
bool dst_test_date_range(uint16_t year, uint16_t doy, pmem::dst_config_t dst) {
|
||||
uint16_t start_doy = day_of_year_of_nth_weekday(year, dst.b.start_month, dst.b.start_which, dst.b.start_weekday);
|
||||
uint16_t end_doy = day_of_year_of_nth_weekday(year, dst.b.end_month, dst.b.end_which, dst.b.end_weekday);
|
||||
return dst_check_date_range(doy, start_doy, end_doy);
|
||||
}
|
||||
|
||||
// Set RTC clock.
|
||||
// If the user has enabled DST, the time entered and passed to this function is interpreted as having been adjusted for DST.
|
||||
// When DST functionality is enabled in pmem, the value stored in the RTC hardware is non-DST time, and we only fudge the time when read.
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "signal.hpp"
|
||||
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
using namespace lpc43xx;
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
namespace rtc_time {
|
||||
|
||||
@ -45,8 +45,9 @@ rtc::RTC now(rtc::RTC& out_datetime);
|
||||
/* Daylight Savings Time functions */
|
||||
void dst_init();
|
||||
rtc::RTC dst_adjust_returned_time(rtc::RTC& datetime);
|
||||
void dst_check_date_range(uint16_t doy);
|
||||
bool dst_check_date_range(uint16_t doy, uint16_t start_doy, uint16_t end_doy);
|
||||
void dst_update_date_range(uint16_t year, uint16_t doy);
|
||||
bool dst_test_date_range(uint16_t year, uint16_t doy, portapack::persistent_memory::dst_config_t dst);
|
||||
uint8_t days_per_month(uint16_t year, uint8_t month);
|
||||
uint8_t current_day_of_week();
|
||||
uint8_t day_of_week(uint16_t year, uint8_t month, uint8_t day);
|
||||
|
Loading…
Reference in New Issue
Block a user