95 lines
2.7 KiB
C++
95 lines
2.7 KiB
C++
#include "utils.h"
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <ctime>
|
|
|
|
int Utils::optionalStoiOrDefault(const std::unordered_map<std::string, std::string>& row,
|
|
const std::string& key, int def) {
|
|
auto it = row.find(key);
|
|
if (it == row.end()) return def;
|
|
const std::string& val = it->second;
|
|
if (isNullOrEmpty(val)) return def;
|
|
try {
|
|
return std::stoi(val);
|
|
} catch (...) {
|
|
return def;
|
|
}
|
|
}
|
|
|
|
double Utils::optionalStodOrDefault(const std::unordered_map<std::string, std::string>& row,
|
|
const std::string& key, double def) {
|
|
auto it = row.find(key);
|
|
if (it == row.end()) return def;
|
|
const std::string& val = it->second;
|
|
if (isNullOrEmpty(val)) return def;
|
|
try {
|
|
return std::stod(val);
|
|
} catch (...) {
|
|
return def;
|
|
}
|
|
}
|
|
|
|
bool Utils::isNullOrEmpty(const std::string& s) {
|
|
return s.empty() || s == "NULL";
|
|
}
|
|
|
|
std::optional<std::chrono::system_clock::time_point> Utils::parseTimestamp(const std::string& iso) {
|
|
std::istringstream ss(iso);
|
|
std::tm tm = {};
|
|
ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");
|
|
if (ss.fail()) {
|
|
ss.clear();
|
|
ss.str(iso);
|
|
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
|
|
if (ss.fail()) return std::nullopt;
|
|
}
|
|
std::time_t time_c = std::mktime(&tm);
|
|
if (time_c == -1) return std::nullopt;
|
|
return std::chrono::system_clock::from_time_t(time_c);
|
|
}
|
|
|
|
std::optional<int> Utils::computeAgeYears(const std::string& birthdate_iso) {
|
|
auto birth_tp = parseTimestamp(birthdate_iso);
|
|
if (!birth_tp) return std::nullopt;
|
|
auto now = std::chrono::system_clock::now();
|
|
|
|
std::time_t birth_time = std::chrono::system_clock::to_time_t(*birth_tp);
|
|
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
|
|
|
|
std::tm birth_tm;
|
|
std::tm now_tm;
|
|
#if defined(_WIN32) || defined(_WIN64)
|
|
localtime_s(&birth_tm, &birth_time);
|
|
localtime_s(&now_tm, &now_time);
|
|
#else
|
|
localtime_r(&birth_time, &birth_tm);
|
|
localtime_r(&now_time, &now_tm);
|
|
#endif
|
|
|
|
int years = now_tm.tm_year - birth_tm.tm_year;
|
|
if (now_tm.tm_mon < birth_tm.tm_mon ||
|
|
(now_tm.tm_mon == birth_tm.tm_mon && now_tm.tm_mday < birth_tm.tm_mday)) {
|
|
years--;
|
|
}
|
|
return years;
|
|
}
|
|
|
|
std::string Utils::buildPgIntArrayLiteral(const std::vector<int>& elems) {
|
|
std::string res = "{";
|
|
for (size_t i = 0; i < elems.size(); ++i) {
|
|
res += std::to_string(elems[i]);
|
|
if (i + 1 < elems.size()) res += ",";
|
|
}
|
|
res += "}";
|
|
return res;
|
|
}
|
|
|
|
std::optional<int> Utils::optionalUid(const std::string& val) {
|
|
if (isNullOrEmpty(val)) return std::nullopt;
|
|
try {
|
|
return std::stoi(val);
|
|
} catch (...) {
|
|
return std::nullopt;
|
|
}
|
|
}
|