Конвертация из секунд в дни, часы, минуты и секунды
struct my_time {
long long day, hour, minute, second;
void set(long long t) {
if (t>=0) {
day = t/60/60/24;
hour = t/60/60-day*24;
minute = t/60-hour*60-day*24*60;
second = t-minute*60-hour*60*60-day*60*60*24;
} else if (t%86400==0) {
day=t/86400;
hour=0;
minute=0;
second=0;
} else {
day = -1;
day += t/86400;
hour = abs(t/60/60-24*day-1);
minute = abs(t/60-hour*60-24*60*day-1);
second = (abs(t-minute*60-hour*60*60-60*60*24*day-1)+1)%60;
}
}
};
Требуется написать структуру времени, метод set получает в параметры кол-во секунд в единицах. Ошибка возникает когда ввожу в метод, к примеру, -600. Поля становятся равными -1 23 49 0, а должны -1 23 50 0. Подскажите, в чём проблема.
Ответы (2 шт):
Напишу в виде ответа, только потому что мест в комментарии не хватает и не красиво. Вообще не презентую на правильный ответ) просто как идея.
Согласен с @wololo очень странная арифметика.
Но попробуйте сделать так:
Если t < 0, то
- Избавляемся от знака.
-t - Находим кол-во дней в
tсекундах, пусть будетday. - Прибавляем к
day+ 1 и возьмем со знаком -. - Отнимаем от
tсекунд, столько секунд, сколько их вdayдней. - Последняя операция это
1 0 0 0 - t(секунд). То есть 1 день -tсекунд.
Надеюсь понятно объяснил идею.
Теперь проверим на примере. Пусть t = -2.
t = -t = 2day = 0-(day + 1) = -1- итоговое кол-во днейt - day * 24 * 60 * 60 = t, т.к.day = 01 0 0 0 - 0 0 0 2 = 0 23 59 58
Получаем ответ: -1 23 59 58
Еще один пример. Пусть t = -179429
t = -t = 179429day = t / (24 * 60 * 60) =2`-(day + 1) = -3- итоговое кол-во днейt - day * 24 * 60 * 60 = 66291 0 0 0 - 0 1 50 29 = 0 22 09 31
Получаем ответ: -3 22 09 31 ???
То есть прибавим к этому времени 6629 секунд и получим -2 0 0 0, а потом останется еще 172800, ну и получим 0 0 0 0, вроде идея имеет место быть.
P.s. вместо 1 0 0 0 - t можно 0 23 59 59 так проще т.к. нужно всего лишь 23 - hours, 59 - minutes, 59 - seconds, и это будет работать потому что t < 86400
Полагаю, вам нужно что-то вроде такого:
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
struct my_time {
long long day, hour, minute, second;
my_time& set(long long t) {
const long long SECONDS_IN_MINUTE = 60LL;
const long long SECONDS_IN_HOUR = SECONDS_IN_MINUTE * 60LL;
const long long SECONDS_IN_DAY = SECONDS_IN_HOUR * 24LL;
day = t / SECONDS_IN_DAY;
t -= day * SECONDS_IN_DAY;
if (t < 0) {
--day;
t += SECONDS_IN_DAY;
}
hour = t / SECONDS_IN_HOUR;
t -= hour * SECONDS_IN_HOUR;
minute = t / SECONDS_IN_MINUTE;
t -= minute * SECONDS_IN_MINUTE;
second = t;
return *this;
}
};
std::ostream& operator<<(std::ostream& out, const my_time& mt) {
out << " " << std::setw(3);
out << mt.day << " " << std::setw(2);
out << mt.hour << " " << std::setw(2);
out << mt.minute << " " << std::setw(2);
out << mt.second;
return out;
}
void print(long long t) {
cout << "t: " << std::setw(7) << t << " my_time: " << my_time().set(t) << endl;
}
int main() {
const long long test[] = {
600, -600, 0,
1, 86399, 86400, 86401, 172799, 172800, 172801,
-1, -86399, -86400, -86401, -172799, -172800, -172801
};
for (auto t: test)
print(t);
}
t: 600 my_time: 0 0 10 0
t: -600 my_time: -1 23 50 0
t: 0 my_time: 0 0 0 0
t: 1 my_time: 0 0 0 1
t: 86399 my_time: 0 23 59 59
t: 86400 my_time: 1 0 0 0
t: 86401 my_time: 1 0 0 1
t: 172799 my_time: 1 23 59 59
t: 172800 my_time: 2 0 0 0
t: 172801 my_time: 2 0 0 1
t: -1 my_time: -1 23 59 59
t: -86399 my_time: -1 0 0 1
t: -86400 my_time: -1 0 0 0
t: -86401 my_time: -2 23 59 59
t: -172799 my_time: -2 0 0 1
t: -172800 my_time: -2 0 0 0
t: -172801 my_time: -3 23 59 59