With xlnt library:
How to convert a date
value to std::string
?
const auto vdate = cell.value<xlnt::date>();
std::string vdates = std::string(vdate);
I get :
error: no matching function for call to ‘std::__cxx11::basic_string<char>::basic_string(const xlnt::date&)’
4259 | std::string vdates = std::string(vdate);
error: no matching function for call to ‘std::__cxx11::basic_string<char>::basic_string(const xlnt::date&)’
4259 | std::string vdates = static_cast<std::string>(vdate);
Although xlnt::cell
has a number of formatting options
cell.number_format(xlnt::number_format::date_yyyymmdd2()); // example
they seem to only affect the visual appearance in Excel and does not affect the outcome when using for example
std::string vdates = cell.to_string();
// or
std::cout << cell << '\n';
but instead shows an integer number representing the date.
xlnt::date
is a rather simple placeholder for three int
s and doesn't seem to support any kind of formatting either directly or by helper functions.
I would therefore convert xlnt::date
to std::chrono::year_month_day
and do all the work in the chrono
domain. If needed, convert the result back to xlnt::date
.
Conversion functions could look like this:
#include <xlnt/xlnt.hpp>
#include <chrono>
std::chrono::year_month_day xlnt2chrono(const xlnt::date& in) {
if(in.is_null()) {
// Extracting year/month/day from xlnt::date
// will throw an exception if you do that when is_null()
// is true. If you want that behavior, just remove this:
return {}; // 0000-00-00
}
return std::chrono::year_month_day(
std::chrono::year(in.get_year()),
std::chrono::month(static_cast<unsigned>(in.get_month())),
std::chrono::day(static_cast<unsigned>(in.get_day())));
}
xlnt::date chrono2xlnt(const std::chrono::year_month_day& in) {
return xlnt::date(static_cast<int>(in.year()),
static_cast<int>(static_cast<unsigned>(in.month())),
static_cast<int>(static_cast<unsigned>(in.day())));
}
Note: The cast to unsigned
in chrono2xlnt
is to extract the numeric month and day and the cast to int
is to provide it to xlnt::date
without getting warnings.
When you then have a std::chrono::year_month_day
formatting it to your pleasure is just a matter of specifying the format to std::format
which will then use the formatter std::formatter<std::chrono::year_month_day>
.
Example:
#include <format>
#include <string>
//...
const auto vdate = cell.value<xlnt::date>();
std::string vdates = std::format("{:%Y-%m-%d}", xlnt2chrono(vdate)); // YYYY-mm-dd