How to independently use `ShowDatePicker` and `ShowTimePicker` to select date/time? [Almost solved]
- Dominant language
- C++
- Stars
- 6.2k
- Forks
- 693
- PR merge metrics
- No merged PRs in 30d
Description
@epezent is it necessary to wrap `ShowDatePicker` and `ShowTimePicker` to a single and independent function/widget to use? I think they are really good to use and beautiful, and did some work to wrap them together. I tried to initialize and use `ShowDatePicker` and `ShowTimePicker` but faced with some problems so I raised this issue. After coding for a while I managed to solve most of them.
Basically, I want to pick a date and a time using the popup widget, save them to a std::string like `2023-05-06 15:24:16`, and show them by `ImGui::Text()`. Also I will save the string to a json file. Next time when I open the program, I will load the date and time from json, parse the string and show them. Also I can initialize the widget again by the loaded date and time, and change them again by the widget.
The desired function/widget may support the following features:
1) [**Solved**] Switch from 12-hour system to 24-hour system. Solved by setting
```cpp
ImPlotStyle &style = ImPlot::GetStyle();
style.Use24HourClock = true;
```
2) [**Partially solved**] Initialize the widget by inputting a UTC string and a TimeZone string under different hour system. Currently 24-hour system. **HAVEN'T TRIED** to initialize under 12-hour system.
3) [**Solved**] Support microseconds.
---
I placed the code below in case someone may need.
```cpp
inline time_t timegm(std::tm *tm) // calculate seconds without timezone
{
#ifdef _WIN32
return _mkgmtime(tm);
#else
return timegm(tm);
#endif
}
//...in render loop
if (ImGui::Button("Change"))
ImGui::OpenPopup("SelectDateTime##");
static std::string strDateTime = "2020-01-01 10:11:23";
static std::string strTimeZone = "UTC-3";
ImPlot_DateTimePicker(strDateTime, strTimeZone);
//...
std::string timestamp2string(std::time_t timestamp)
{
std::tm *tm = std::gmtime(×tamp);
char buffer[80];
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm);
return buffer;
}
int timezone2int(const std::string tzstring)
{
size_t found = tzstring.find("UTC");
if (found != std::string::npos)
{
std::string number_str = tzstring.substr(found + 3);
std::stringstream ss(number_str);
int number;
ss >> number;
return number;
}
else
return 0;
}
std::string ImPlot_DateTimePicker(std::string &UTCdatetime, std::string TimeZone = "UTC+0")
{
std::tm tm = {};
std::stringstream ss(UTCdatetime);
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S.%f");
static std::time_t timestamp0 = timegm(&tm) + timezone2int(TimeZone) * 3600; // current timestamp of current timezone
std::tm tm_midnight = tm;
tm_midnight.tm_hour = tm_midnight.tm_min = tm_midnight.tm_sec = 0;
static std::time_t timestamp_midnight = timegm(&tm_midnight);
static std::time_t deltaDate = timestamp0 - timestamp_midnight;
if (ImGui::BeginPopup("SelectDateTime##"))
{
static int PickerLevel = 0;
static ImPlotTime time_selected = timestamp0;
static ImPlotTime date_selected = timestamp0;
ImPlotStyle &style = ImPlot::GetStyle();
style.Use24HourClock = true;
// `TimePicker` only changes hour, minute, second around initial timestamp `time_stamp0`
ImPlot::ShowTimePicker("##time", &time_selected);
std::time_t deltaTime = time_selected.S - timestamp0; // delta second of `current timestamp selection - initial timestamp` by Time Picker
// set milliseconds besides `TimePicker`
static int ms = 0;
std::size_t dotPos = UTCdatetime.find_first_of('.');
if (dotPos != std::string::npos)
ms = stoi(UTCdatetime.substr(dotPos + 1));
ImGui::SameLine();
ImGui::Text(".");
ImGui::SameLine();
ImGui::PushItemWidth(5 * ImGui::GetFontSize());
ImGui::InputInt("##milliseconds", &ms);
ImGui::PopItemWidth();
ms = CLAMP(ms, 0, 999);
std::stringstream ss;
ss << std::setw(3) << std::setfill('0') << ms;
ImGui::Separator();
// `DatePicker` directly select and return timestamp at midnight (i.e., timestamp of different date at 00:00:00)
ImPlot::ShowDatePicker("##date", &PickerLevel, &date_selected, &date_selected);
std::time_t timestamp = date_selected.S + deltaDate + deltaTime; // current timestamp
UTCdatetime = timestamp2string(timestamp) + "." + ss.str();
ImGui::EndPopup();
}
}
```
---
Screenshot. The time zone selection combobox is not included in the code
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.