#c
#c
Вопрос:
У меня есть вопрос об управлении датой и временем в c . В моей программе есть два класса Plane и Flight.
Моя плоскость будет состоять из данных в виде:
string tailNumber;//Plane's unique trait
vector<vector<string>> planeSchedule;//2D string vector to contain plane's depature date and arrival date
Мой класс полета будет содержать данные в виде:
string tailNumber;//Plane's unique trait
string departureDate;
string arrivalDate;
В моем основном классе я буду вводить значения для DepartureDate и ArrivalDate в формате: «ГГГГ / ММ / ДД ЧЧ: ММ», например: "2019/04/15 10:30" and "2019/04/16 9:30"
(я буду использовать 24-часовой формат, и время будет GMT).
Мой вопрос заключается в том, как мне преобразовать две приведенные выше строки в надлежащий формат для сохранения в моем planeSchedule, чтобы я мог избежать конфликта времени в planeSchedule.
Например, если в следующий раз я добавлю рейс с датой вылета и прибытия между: 2019/04/15 10:30" and "2019/04/16 9:30"
, например: "2019/04/15 13:30" and "2019/04/16 7:30"
, я получу сообщение об ошибке типа «Конфликт рейсов, самолет недоступен для полета».
Мой профессор рекомендует использовать unsigned long int для хранения времени, но я действительно не знаю, с чего начать, чтобы решить эту проблему. Приветствуется любая помощь / предложение.
Комментарии:
1. время обычно хранится в виде целого числа, которое представляет количество единиц (секунда, миллисекунда, 100 наносекунд и т.д.) от эпохи. Смотрите en.wikipedia.org/wiki/Unix_time#Encoding_time_as_a_number
Ответ №1:
Основное место, касающееся дат и времени в C , является <chrono>
. Кое-что из этого есть у нас с C 11, кое-что, как мы увидим, появится с C 20. Это работает в сочетании с утилитами даты и времени в <ctime>
стиле C, которых может быть даже достаточно для ваших целей.
Попытка обработать дату / время либо в виде целых чисел, либо в виде строк, анализируя их из входных данных, сравнивая и преобразуя их в строки для вывода, эффективно приведет к тому, что вы переопределите части того, что уже есть в этих заголовках (также известное как «изобретение колеса»).
Комментарии:
1. Я поражен, что профессора на самом деле рекомендуют избитые вещи вроде «использовать беззнаковый long int для хранения времени», как будто это был 1970 год… неудивительно, что люди уходят с таких курсов, думая «C сложный», хотя на самом деле это не так.
2. Вот рабочий предварительный просмотр 20
<chrono>
бит C : github.com/HowardHinnant/date Это находится в пространстве именdate
вместоnamespace std::chrono
.
Ответ №2:
У меня есть два совета, основанных на многолетнем опыте работы с системами, которые делали это плохо 🙂
Первое — не хранить информацию о дате и времени в виде строк или целых значений, особенно когда C имеет очень хорошую поддержку для этого в std::chrono
. Если вы используете правильные типы, сравнения и манипуляции становятся относительно простыми.
Во-вторых, убедитесь, что вы используете UTC для всех времен. Вы должны преобразовать местное время в UTC как можно скорее после их получения и преобразовать обратно в местное как можно позже при их представлении. Это также значительно упростит сравнения.
В качестве примера, вот полная программа, которая демонстрирует простоту (a) в действии:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
using std::chrono::system_clock;
using std::chrono::duration_cast;
namespace {
system_clock::time_point getTimePoint(std::string strTime) {
std::tm myTm = {};
std::stringstream ss(strTime.c_str());
ss >> std::get_time(amp;myTm, "%Y/%m/%d %H:%M");
return system_clock::from_time_t(std::mktime(amp;myTm));
}
void outputTime(const char *desc, system_clock::time_point amp;tp) {
std::time_t now = system_clock::to_time_t(tp);
std::cout << desc
<< std::put_time(std::localtime(amp;now), "%Y-%m-%d %H:%M") << "n";
}
}
int main() {
std::string startTime = "2019/04/15 10:30";
std::string endTime = "2019/04/16 09:30";
auto startTp = getTimePoint(startTime);
auto endTp = getTimePoint(endTime);
outputTime("Start time: ", startTp);
outputTime(" End time: ", endTp);
auto duration = duration_cast<std::chrono::minutes>(endTp - startTp);
std::cout << "nThere are " << duration.count() << " minutes between "
<< startTime << " and " << endTime << "n";
}
Результат этой программы является:
Start time: 2019-04-15 10:30
End time: 2019-04-16 09:30
There are 1380 minutes between 2019/04/15 10:30 and 2019/04/16 09:30
(a) Да, программа может показаться достаточно большой, но это только из-за материала, делающего ее полноценной программой. Функции getTimePoint
и outputTime
показывают, как выполнять преобразование в временные точки и из них, а суть простоты заключается в строке, содержащей duration_cast
количество минут между двумя временными точками.
Комментарии:
1. Можете ли вы дать мне несколько инструкций по использованию std:: chrono для решения моей проблемы, я ценю все, что угодно.
2. @DatTo: Это было бы проще, если бы вы могли свести «вашу проблему» к одной единственной функциональности. В нынешнем виде «ваша проблема» — это все, начиная с синтаксического анализа входных данных и заканчивая сохранением значений и некоторым не очень четко определенным сравнением с выводом. Т.Е. «напишите мою программу для меня», что обычно не делается в Stackoverflow. Выберите что-нибудь конкретное, и я уверен, мы могли бы показать вам несколько строк примера кода.