162 lines
6.0 KiB
C++
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 ¤tDayDate,
|
||
|
std::string const ¤tDayTime,
|
||
|
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(), ¤t_time_tm)) {
|
||
|
return ActiveTimeRange();
|
||
|
}
|
||
|
auto const dayOfWeek = TariffUtils::GetDayOfWeek(¤t_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();
|
||
|
}
|