Я нашел этот код:
sort(filenames.begin(), filenames.end(), [](const string& a, const string& b)
{
auto getEpochTime = [](const string& s) -> time_t
{
std::string a = s.substr(s.find("trades") + 7, 10);
std::istringstream date_s(a);
struct tm date_c;
date_s >> std::get_time( &date_c, "%Y-%m-%d" );
std::time_t seconds = std::mktime( & date_c );
return seconds;
};
time_t partA = getEpochTime(a), partB = getEpochTime(b);
//time_t partA = GetDate(a), partB = GetDate(b);
cout << a << " " << partA << " " << partB << " " << b << endl;
return partA < partB;
});
мои имена файлов — это вектор с этими значениями:
./files/BTCUSDT-trades-2020-01-01.csv
./files/BTCUSDT-trades-2020-01-03.csv
./files/BTCUSDT-trades-2020-01-04.csv
./files/BTCUSDT-trades-2020-01-08.csv
./files/BTCUSDT-trades-2020-01-05.csv
./files/BTCUSDT-trades-2020-01-06.csv
./files/BTCUSDT-trades-2020-01-09.csv
./files/BTCUSDT-trades-2020-01-10.csv
И как видите, после сортировки это явно не сработало. По какой-то причине при печати a и partA внутри функции сортировки я нахожу странные значения:
./files/BTCUSDT-trades-2020-01-09.csv 1578525308 1577834108 ./files/BTCUSDT-trades-2020-01-01.csv
./files/BTCUSDT-trades-2020-01-09.csv 1536583284 1578400884 ./files/BTCUSDT-trades-2020-01-07.csv
./files/BTCUSDT-trades-2020-01-09.csv 1578573684 1578660084 ./files/BTCUSDT-trades-2020-01-10.csv
./files/BTCUSDT-trades-2020-01-09.csv 1578573684 1578314484 ./files/BTCUSDT-trades-2020-01-06.csv
./files/BTCUSDT-trades-2020-01-02.csv -504396806053 1577834108 ./files/BTCUSDT-trades-2020-01-01.csv
Есть идеи, что я сделал не так, пожалуйста?
В качестве комментария перед тем, как я прочитаю код, эти даты выглядят как гггг-мм-дд, поэтому вы можете просто отсортировать их как строки. Я предпочитаю формат ISO, главным образом по этой причине.
@NathanOliver, извини, просто я поменял имя в последнюю минуту, так что это та же самая функция
Короткий ответ: не используйте преобразование времени, вы можете просто отсортировать строки лексикографически:
std::sort(filenames.begin(), filenames.end());
Длинный ответ: вам не удалось правильно инициализировать объект std::tm
, поэтому он содержит мусорные значения.
Из документации std::mktime:
Если объект
std::tm
был получен изstd::get_time
или POSIXstrptime
, значениеtm_isdst
является неопределенным и должно быть установлено явно перед вызовомmktime
.
И из документации для std::get_time:
[...] не указано, обнуляет ли эта функция поля в
*tmb
, которые не установлены непосредственно спецификаторами преобразования, которые появляются вfmt
: переносимые программы должны инициализировать каждое поле*tmb
до нуля перед вызовомstd::get_time
.
Вам необходимо инициализировать все, что не установлено std::get_time
:
// ...
struct tm date_c;
date_c.tm_sec = 0;
date_c.tm_min = 0;
date_c.tm_hour = 0;
date_c.tm_isdst = 0;
date_s >> std::get_time( &date_c, "%Y-%m-%d" );
// ...
Или проще: tm date_c = {};
Что делает
getEpochTime
? Похоже, вам, возможно, придется научиться использовать отладчик для пошагового выполнения кода. С помощью хорошего отладчика вы можете выполнять программу построчно и видеть, где она отклоняется от ожидаемого. Это важный инструмент, если вы собираетесь заниматься программированием. Дальнейшее чтение: Как отлаживать небольшие программы и Руководство по отладке