MOBILISIS-Calculator/library/src/tariff_utils.cpp

162 lines
6.0 KiB
C++

#include "tariff_utils.h"
#include <assert.h>
#include <ctime>
/// <inheritdoc/>
time_t TariffUtils::GetCurrentLocalTime() {
time_t epoch = time(NULL);
struct tm *local_time = localtime(&epoch);
if (local_time) {
// local_time->tm_isdst > 0: DST is in effect
// local_time->tm_isdst = 0: DST is not in effect
// and a negative value means that mktime() should use timezone
// information to attempt to determine whether DST is in effect
// at the specified time.
local_time->tm_isdst = -1;
return mktime(local_time);
}
return -1;
}
/// <inheritdoc/>
bool TariffUtils::DateToStructTm(const char* dateStr, struct tm *t) {
return (strptime(dateStr, "%Y-%m-%d", t) != 0);
}
static time_t DateTimeStrToTime(std::string const &dateTimeStr) {
struct tm t = {};
if (strptime(dateTimeStr.c_str(), "%Y-%m-%dT%H:%M:%S", &t) != 0) {
t.tm_isdst = -1;
return mktime(&t);
}
return -1;
}
/// <inheritdoc/>
bool TariffUtils::TimeToStructTm(const char* timeStr, struct tm *t) {
return (strptime(timeStr, "%H:%M:%S", t) != 0);
}
/// <inheritdoc/>ateTimeToStructTm(char const* dateTimeStr) {
bool TariffUtils::DateTimeToStructTm(char const* dateTimeStr, struct tm *t) {
return (strptime(dateTimeStr, "%Y-%m-%dT%H:%M:%S", t) != 0);
}
/// <inheritdoc/>
DayOfWeek TariffUtils::GetDayOfWeek(struct tm const *t) {
return (DayOfWeek)t->tm_wday;
}
/// <inheritdoc/>
bool TariffUtils::IsSpecialDay(TariffConfiguration const* tariff_cfg,
const char* datetime, int& specialDayId) {
for (size_t i = 0; i < tariff_cfg->SpecialDays.size(); i++) {
TariffSpecialDays const &sd = tariff_cfg->SpecialDays[i];
char const *sdt = sd.ped_date_start.c_str();
char const *edt = sd.ped_date_end.c_str();
// format datetime: 2022-12-04T22:30:30
// format sdt resp. edt: 2022-12-25
// comparing the strings gives the result
if (strncmp(datetime, sdt, strlen(sdt)) >= 0
&& strncmp(datetime, edt, strlen(edt)) <= 0) {
specialDayId = sd.ped_id;
return true;
}
}
return false;
}
bool TariffUtils::PriceForSpecialDay(TariffConfiguration const* tariff_cfg,
int specialDayId, double *price) {
for (size_t j = 0; j <= tariff_cfg->SpecialDaysWorktime.size(); j++) {
int wt_id = tariff_cfg->SpecialDaysWorktime.at(j).pedwt_period_exc_day_id;
if (specialDayId == wt_id) {
*price = tariff_cfg->SpecialDaysWorktime.at(j).pedwt_price;
return true;
}
}
return false;
}
/// <inheritdoc/>
bool TariffUtils::ValidateParkingTicket(TariffConfiguration const */*tariff_cfg*/,
time_t /*initial*/,
int /*durationMin*/,
double /*price*/,
TariffTimeRange /*time_range*/,
bool /*isSpecialDay*/,
int /*spec_day_id*/) {
// TODO
return true;
}
static ActiveTimeRange computeActiveTimeRange(std::string const &currentDayDate,
std::string const &currentDayTime,
std::string const &time_from,
std::string const &time_to) {
ActiveTimeRange result;
if (currentDayTime.compare(time_from) >= 0
&& currentDayTime.compare(time_to) <= 0) {
std::string timeFrom = currentDayDate + "T" + time_from;
std::string timeTo = currentDayDate + "T" + time_to;
time_t const from = DateTimeStrToTime(timeFrom);
time_t const to = DateTimeStrToTime(timeTo);
if (from != -1 && to != -1) {
result.timeRange.time_from = from;
result.timeRange.time_to = to;
result.isActive = true;
}
}
return result;
}
/// <inheritdoc/>
ActiveTimeRange
TariffUtils::isParkingTimeRangeActive(TariffConfiguration* tariff_cfg,
std::string datetimeStr,
bool isSpecialDay = false,
int spec_day_id = -1) {
size_t const pos = datetimeStr.find_first_of('T');
if (pos == std::string::npos || pos == 0 || pos >= datetimeStr.size()-1) {
return ActiveTimeRange();
}
// split dateTime at 'T'
std::string const currentDayDate = datetimeStr.substr(0, pos - 1);
std::string const currentDayTime = datetimeStr.substr(pos + 1);
// return (strptime(dateStr, "%Y-%m-%d", t) != 0);
if (isSpecialDay) {
for (size_t i = 0; i < tariff_cfg->SpecialDaysWorktime.size(); i++) {
TariffSpecialDaysWorktime const &sdwt = tariff_cfg->SpecialDaysWorktime[i];
if (sdwt.pedwt_period_exc_day_id == spec_day_id) {
std::string const &time_from = sdwt.pedwt_time_from;
std::string const &time_to = sdwt.pedwt_time_to;
return computeActiveTimeRange(currentDayDate, currentDayTime,
time_from, time_to);
}
}
} else {
struct tm current_time_tm = {};
if (!TariffUtils::DateTimeToStructTm(datetimeStr.c_str(), &current_time_tm)) {
return ActiveTimeRange();
}
auto const dayOfWeek = TariffUtils::GetDayOfWeek(&current_time_tm);
for (size_t i = 0; i < tariff_cfg->WeekDaysWorktime.size(); i++) {
TariffWeekDaysWorktime const &wdwt = tariff_cfg->WeekDaysWorktime[i];
if (wdwt.pwd_period_day_in_week_id == dayOfWeek) {
std::string const &time_from = wdwt.pwd_time_from;
std::string const &time_to = wdwt.pwd_time_to;
return computeActiveTimeRange(currentDayDate, currentDayTime,
time_from, time_to);
}
}
}
return ActiveTimeRange();
}