Skip to content

Commit 040d985

Browse files
HenrZureneSchm
andauthored
1195 Formatter for date to have consistent Format (#1198)
- Formatter to print date objects Co-authored-by: reneSchm <49305466+reneSchm@users.noreply.github.com>
1 parent edb2f59 commit 040d985

File tree

6 files changed

+104
-40
lines changed

6 files changed

+104
-40
lines changed

cpp/memilio/utils/date.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define EPI_UTILS_DATE_H
2222

2323
#include "memilio/io/io.h"
24+
#include "memilio/utils/logging.h"
2425
#include <string>
2526
#include <iostream>
2627
#include <tuple>
@@ -106,11 +107,27 @@ struct Date {
106107
//@}
107108

108109
/**
109-
* gtest printer.
110+
* Formats the date into a string in ISO 8601 format (YYYY-MM-DD).
111+
* @return A string representing the date in ISO 8601 format.
110112
*/
111-
friend void PrintTo(const Date& self, std::ostream* os)
113+
std::string to_iso_string() const
112114
{
113-
*os << self.year << "." << self.month << "." << self.day;
115+
// the format after ":" reads as
116+
// 1) '0' -> fill with zeros
117+
// 2) '>' -> align text right
118+
// 3) '4' or '2' -> specify the width (4 for year, 2 for month and day)
119+
return fmt::format("{:0>4}-{:0>2}-{:0>2}", year, month, day);
120+
}
121+
122+
/**
123+
* Overload for stream operator to use the ISO 8601 format.
124+
* @param os Output stream.
125+
* @param date Date to output.
126+
* @return Reference to the output stream.
127+
*/
128+
friend std::ostream& operator<<(std::ostream& os, const Date& date)
129+
{
130+
return os << date.to_iso_string();
114131
}
115132

116133
/**
@@ -156,6 +173,15 @@ struct Date {
156173
static constexpr std::array<int, 12> month_lengths_leap_year = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
157174
};
158175

176+
/**
177+
* @brief Format date objects using the ISO notation for logging with spdlog.
178+
* @param d date object.
179+
*/
180+
inline std::string format_as(const mio::Date& d)
181+
{
182+
return d.to_iso_string();
183+
}
184+
159185
/**
160186
* @brief Computes the length of a month for a given date.
161187
* @param date date.

cpp/models/ide_secir/parameters_io.h

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -288,17 +288,11 @@ IOResult<void> set_initial_flows(Model& model, const ScalarType dt, const std::v
288288
return a.date < b.date;
289289
});
290290
auto min_date = min_date_entry->date;
291-
292-
std::string min_date_string =
293-
std::to_string(min_date.day) + "." + std::to_string(min_date.month) + "." + std::to_string(min_date.year);
294291
// Get first date that is needed.
295-
mio::Date min_offset_date = offset_date_by_days(date, int(min_offset_needed));
296-
std::string min_offset_date_string = std::to_string(min_offset_date.day) + "." +
297-
std::to_string(min_offset_date.month) + "." +
298-
std::to_string(min_offset_date.year);
299-
log_warning("RKI data is needed from " + min_offset_date_string +
300-
" to compute initial values. RKI data is only available from " + min_date_string +
301-
". Missing dates were set to 0.");
292+
mio::Date min_offset_date = offset_date_by_days(date, int(min_offset_needed));
293+
log_warning("RKI data is needed from {} to compute initial values. RKI data is only available from {}. Missing "
294+
"dates were set to 0.",
295+
min_offset_date, min_date);
302296
}
303297

304298
//--- Calculate the flows "after" InfectedNoSymptomsToInfectedSymptoms (that were set above using rki_data). ---

cpp/models/ode_secir/parameters_io.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,8 @@ IOResult<void> set_confirmed_cases_data(std::vector<Model<FP>>& model, std::vect
143143
}
144144
}
145145
else {
146-
log_warning("No infections reported on date " + std::to_string(date.year) + "-" +
147-
std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
148-
std::to_string(region[node]) + ". Population data has not been set.");
146+
log_warning("No infections reported on date {} for region {}. Population data has not been set.", date,
147+
region[node]);
149148
}
150149
}
151150
return success();
@@ -196,8 +195,9 @@ IOResult<void> set_divi_data(std::vector<Model<FP>>& model, const std::string& p
196195
{
197196
// DIVI dataset will no longer be updated from CW29 2024 on.
198197
if (!is_divi_data_available(date)) {
199-
log_warning("No DIVI data available for date: {}-{}-{}", date.year, date.month, date.day,
200-
". ICU compartment will be set based on Case data.");
198+
log_warning("No DIVI data available for date: {}. "
199+
"ICU compartment will be set based on Case data.",
200+
date);
201201
return success();
202202
}
203203
std::vector<double> sum_mu_I_U(vregion.size(), 0);

cpp/models/ode_secirts/parameters_io.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,9 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
421421
}
422422
}
423423
if (std::accumulate(num_InfectedSymptoms[county].begin(), num_InfectedSymptoms[county].end(), 0.0) == 0) {
424-
log_warning("No infections for unvaccinated reported on date " + std::to_string(date.year) + "-" +
425-
std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
426-
std::to_string(region[county]) + ". Population data has not been set.");
424+
log_warning(
425+
"No infections for unvaccinated reported on date {} for region {}. Population data has not been set.",
426+
date, region[county]);
427427
}
428428
}
429429

@@ -478,9 +478,9 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
478478
num_timm1[county][i];
479479
}
480480
if (std::accumulate(num_InfectedSymptoms[county].begin(), num_InfectedSymptoms[county].end(), 0.0) == 0) {
481-
log_warning("No infections for partially vaccinated reported on date " + std::to_string(date.year) + "-" +
482-
std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
483-
std::to_string(region[county]) + ". Population data has not been set.");
481+
log_warning("No infections for partially vaccinated reported on date {} for region {}. "
482+
"Population data has not been set.",
483+
date, region[county]);
484484
}
485485
}
486486

@@ -536,9 +536,9 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
536536
num_timm2[county][i];
537537
}
538538
if (std::accumulate(num_InfectedSymptoms[county].begin(), num_InfectedSymptoms[county].end(), 0.0) == 0) {
539-
log_warning("No infections for vaccinated reported on date " + std::to_string(date.year) + "-" +
540-
std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
541-
std::to_string(region[county]) + ". Population data has not been set.");
539+
log_warning("No infections for vaccinated reported on date {} for region {}. "
540+
"Population data has not been set.",
541+
date, region[county]);
542542
}
543543
}
544544
return success();
@@ -663,8 +663,9 @@ IOResult<void> set_divi_data(std::vector<Model>& model, const std::string& path,
663663
{
664664
// DIVI dataset will no longer be updated from CW29 2024 on.
665665
if (!is_divi_data_available(date)) {
666-
log_warning("No DIVI data available for date: {}-{}-{}", date.year, date.month, date.day,
667-
". ICU compartment will be set based on Case data.");
666+
log_warning("No DIVI data available for date: {}. "
667+
"ICU compartment will be set based on Case data.",
668+
date);
668669
return success();
669670
}
670671
std::vector<FP> sum_mu_I_U(vregion.size(), 0);

cpp/models/ode_secirvvs/parameters_io.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ IOResult<void> set_confirmed_cases_data(std::vector<Model>& model,
196196

197197
// }
198198
if (std::accumulate(num_InfectedSymptoms[county].begin(), num_InfectedSymptoms[county].end(), 0.0) == 0) {
199-
log_warning("No infections for unvaccinated reported on date " + std::to_string(date.year) + "-" +
200-
std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
201-
std::to_string(region[county]) + ". Population data has not been set.");
199+
log_warning(
200+
"No infections for unvaccinated reported on date {} for region {}. Population data has not been set.",
201+
date, region[county]);
202202
}
203203
}
204204

@@ -284,9 +284,9 @@ IOResult<void> set_confirmed_cases_data(std::vector<Model>& model,
284284
}
285285
// }
286286
if (std::accumulate(num_InfectedSymptoms[county].begin(), num_InfectedSymptoms[county].end(), 0.0) == 0) {
287-
log_warning("No infections for partially vaccinated reported on date " + std::to_string(date.year) + "-" +
288-
std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
289-
std::to_string(region[county]) + ". Population data has not been set.");
287+
log_warning("No infections for partially vaccinated reported on date {} for region {}. "
288+
"Population data has not been set.",
289+
date, region[county]);
290290
}
291291
}
292292

@@ -370,9 +370,9 @@ IOResult<void> set_confirmed_cases_data(std::vector<Model>& model,
370370
}
371371
}
372372
if (std::accumulate(num_InfectedSymptoms[county].begin(), num_InfectedSymptoms[county].end(), 0.0) == 0) {
373-
log_warning("No infections for vaccinated reported on date " + std::to_string(date.year) + "-" +
374-
std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
375-
std::to_string(region[county]) + ". Population data has not been set.");
373+
log_warning("No infections for vaccinated reported on date {} for region {}. "
374+
"Population data has not been set.",
375+
date, region[county]);
376376
}
377377
}
378378

@@ -428,8 +428,9 @@ IOResult<void> set_divi_data(std::vector<Model>& model, const std::string& path,
428428
{
429429
// DIVI dataset will no longer be updated from CW29 2024 on.
430430
if (!is_divi_data_available(date)) {
431-
log_warning("No DIVI data available for date: {}-{}-{}", date.year, date.month, date.day,
432-
". ICU compartment will be set based on Case data.");
431+
log_warning("No DIVI data available for date: {}. "
432+
"ICU compartment will be set based on Case data.",
433+
date);
433434
return success();
434435
}
435436
std::vector<double> sum_mu_I_U(vregion.size(), 0);

cpp/tests/test_date.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,45 @@ TEST(TestDate, getOffset)
170170
offset = mio::get_offset_in_days({2019, 11, 30}, {2020, 11, 30});
171171
EXPECT_EQ(offset, -366);
172172
}
173+
174+
TEST(TestDate, toIsoString)
175+
{
176+
EXPECT_EQ(mio::Date(2020, 9, 2).to_iso_string(), "2020-09-02");
177+
EXPECT_EQ(mio::Date(2021, 8, 30).to_iso_string(), "2021-08-30");
178+
EXPECT_EQ(mio::Date(2021, 3, 4).to_iso_string(), "2021-03-04");
179+
EXPECT_EQ(mio::Date(2021, 1, 1).to_iso_string(), "2021-01-01");
180+
EXPECT_EQ(mio::Date(2020, 2, 29).to_iso_string(), "2020-02-29");
181+
}
182+
183+
TEST(TestDate, streamOutput)
184+
{
185+
std::ostringstream oss1;
186+
oss1 << mio::Date(2020, 9, 2);
187+
EXPECT_EQ(oss1.str(), "2020-09-02");
188+
189+
std::ostringstream oss2;
190+
oss2 << mio::Date(2021, 8, 30);
191+
EXPECT_EQ(oss2.str(), "2021-08-30");
192+
193+
std::ostringstream oss3;
194+
oss3 << mio::Date(2021, 3, 4);
195+
EXPECT_EQ(oss3.str(), "2021-03-04");
196+
197+
std::ostringstream oss4;
198+
oss4 << mio::Date(2021, 1, 1);
199+
EXPECT_EQ(oss4.str(), "2021-01-01");
200+
201+
std::ostringstream oss5;
202+
oss5 << mio::Date(2020, 2, 29);
203+
EXPECT_EQ(oss5.str(), "2020-02-29");
204+
}
205+
206+
TEST(TestDate, formatViaFmt)
207+
{
208+
EXPECT_EQ(fmt::format("{}", mio::Date(2020, 9, 2)), "2020-09-02");
209+
EXPECT_EQ(fmt::format("{}", mio::Date(2021, 8, 30)), "2021-08-30");
210+
EXPECT_EQ(fmt::format("{}", mio::Date(2021, 1, 1)), "2021-01-01");
211+
EXPECT_EQ(fmt::format("{}", mio::Date(2020, 2, 29)), "2020-02-29");
212+
EXPECT_EQ(fmt::format("{}", mio::Date(2021, 3, 4)), "2021-03-04");
213+
EXPECT_EQ(fmt::format("Todays date is: {}", mio::Date(2021, 12, 31)), "Todays date is: 2021-12-31");
214+
}

0 commit comments

Comments
 (0)