У меня есть программа wxWidgets с wxDatePickerCtrl, и я использую date.h для работы с датами в C++17.
Когда дата изменяется, я хочу получить строковое представление текущей выбранной даты (с помощью date::format()).
Я делаю это следующим образом:
[*]Получить дату из wxDateEvent [*]Вызов метода GetTicks, который возвращает time_t [*]Преобразовать в std::chrono::system_lock::time_point с помощью from_time_t() [*]Наконец конвертируйте в date::days
При инициализации даты в порядке. Но когда я возвращаюсь назад на один день, date::floor вычисляет дату на два дня назад. Однако date::ceil правильно вычисляет дату.
Смотрите прикрепленный скриншот:

МИР:
#include #include #ifndef WX_PRECOMP #include #endif #include #include класс MainFrame Final: общедоступный wxFrame { публика: МейнФрейм() : wxFrame(nullptr, wxID_ANY, "wxDatesAndDateDotH") , pDateCtrl(nullptr) , pDateLabel(nullptr) , pDateDotHFloorLabel(nullptr) , pDateDotHCeilLabel(nullptr) { СоздатьЭлементы управления(); Элементы управления заливкой(); Связывать( wxEVT_DATE_CHANGED, &MainFrame::OnDateSelection, этот, wxdIDC_DATESLCTR ); } виртуальный ~MainFrame() = по умолчанию; void OnDateSelection (wxDateEvent& событие) { pDateLabel->SetLabel(wxString::Format("Выбрана дата: %s", event.GetDate().FormatISODate())); авто& eventDate = event.GetDate(); auto dateTicks = eventDate.GetTicks(); auto dateFloor = date::floor(std::chrono::system_clock::from_time_t(dateTicks)); auto dateCeil = date::ceil(std::chrono::system_clock::from_time_t(dateTicks)); pDateDotHFloorLabel->SetLabel(wxString::Format("date::floor = %s", date::format("%F", dateFloor))); pDateDotHCeilLabel->SetLabel(wxString::Format("date::ceil = %s", date::format("%F", dateCeil))); } частный: недействительный CreateControls() { auto mainPanel = новый wxPanel (это, wxID_ANY); auto mainSizer = новый wxBoxSizer(wxVERTICAL); mainPanel->SetSizer(mainSizer); auto starterLabel = новый wxStaticText (mainPanel, wxID_ANY, «wxDates»); mainSizer->Add(starterLabel, wxSizerFlags().Center()); auto dateSizer = новый wxBoxSizer(wxHORIZONTAL); mainSizer-> Добавить (dateSizer); auto dateLabel = новый wxStaticText(mainPanel, wxID_ANY, "Дата: "); dateSizer->Add(dateLabel, wxSizerFlags().Border(wxALL, 5).CenterVertical()); pDateCtrl = новый wxDatePickerCtrl(mainPanel, wxdIDC_DATESLCTR, wxDateTime::Now()); dateSizer->Add(pDateCtrl, wxSizerFlags().Border(wxALL, 5)); pDateLabel = новый wxStaticText(mainPanel, wxID_ANY, «Выбранная дата: --»); mainSizer->Add(pDateLabel, wxSizerFlags().Border(wxALL, 5)); pDateDotHFloorLabel = новый wxStaticText(mainPanel, wxID_ANY, "date::floor = --"); mainSizer->Add(pDateDotHFloorLabel, wxSizerFlags().Border(wxALL, 5)); pDateDotHCeilLabel = новый wxStaticText(mainPanel, wxID_ANY, "date::ceil = --"); mainSizer->Add(pDateDotHCeilLabel, wxSizerFlags().Border(wxALL, 5)); } недействительный FillControls() { auto dateTimeNow = wxDateTime::Now(); автоматический dateTimeNowTicks = dateTimeNow.GetTicks(); pDateLabel->SetLabel(wxString::Format("Выбрана дата: %s", dateTimeNow.FormatISODate())); auto dateFloor = date::floor(std::chrono::system_lock::from_time_t(dateTimeNowTicks)); auto dateCeil = date::ceil(std::chrono::system_lock::from_time_t(dateTimeNowTicks)); pDateDotHFloorLabel->SetLabel(wxString::Format("date::floor = %s", date::format("%F", dateFloor))); pDateDotHCeilLabel->SetLabel(wxString::Format("date::ceil = %s", date::format("%F", dateCeil))); } wxDatePickerCtrl* pDateCtrl; wxStaticText* pDateLabel; wxStaticText* pDateDotHFloorLabel; wxStaticText* pDateDotHCeilLabel; перечисление { wxdIDC_DATESLCTR = wxID_HIGHEST + 1001 }; }; Приложение класса: общедоступное wxApp { публика: Приложение() = по умолчанию; виртуальное ~Application() = по умолчанию; bool OnInit() переопределить { автоматический кадр = новый MainFrame(); рамка-> Показать (правда); SetTopWindow (кадр); вернуть истину; } }; wxIMPLEMENT_APP (Приложение); Мой вопрос: почему date::floor вычисляет дату на 2 дня раньше, когда она «инициализируется» из time_t?
Мою проблему можно решить, используя date::ceil в конце дня, но мне интересно узнать о date::floor.
Мой вариант использования заключается в том, что вы не можете заглянуть в будущее, только сегодня и прошлые даты.
Мобильная версия