std :: time_point от и до std :: string - PullRequest
2 голосов
/ 29 мая 2020

Я пытаюсь заменить некоторый код boost :: gregorian, используя c ++ 20 std :: chrono, надеясь удалить зависимость от сборки boost. Код читает и записывает в json (с использованием nlohmann), поэтому возможность конвертировать даты в std :: string и из него имеет решающее значение.

Использование g ++ 9.3.0 в Ubuntu 20.04. 2 ошибки времени компиляции, один на std :: chrono :: parse (), а второй на std :: put_time ()

Для ошибки A на std :: chrono :: parse () я вижу здесь эта поддержка календаря (P0355R7), которая включает chrono :: parse, еще не доступна в g cc libstdc ++. Кто-нибудь знает, правильно ли это или есть ссылка на ETA для этого? или что-то не так с тем, как я вызываю parse ()?

Для ошибки B для std :: put_time (): поскольку std: put_time () задокументирован как C ++ 11, чувствую, что я здесь не хватает чего-то глупого. Также нахожу странным необходимость скрыться через time_t и tm c. Есть ли лучший способ преобразовать std :: chrono :: time_point непосредственно в std :: string, не прибегая к c?

#include <chrono>
#include <string>
#include <sstream>
#include <iostream>

int main(int argc, char *argv[]) {
    std::chrono::system_clock::time_point myDate;

    //Create time point from string
    //Ref: https://en.cppreference.com/w/cpp/chrono/parse
    std::stringstream ss;
    ss << "2020-05-24";
    ss >> std::chrono::parse("%Y-%m-%e", myDate);   //error A: ‘parse’ is not a member of ‘std::chrono’

    //Write time point to string
    //https://en.cppreference.com/w/cpp/io/manip/put_time
    //http://cgi.cse.unsw.edu.au/~cs6771/cppreference/en/cpp/chrono/time_point.html
    std::string dateString;
    std::time_t dateTime = std::chrono::system_clock::to_time_t(myDate);
    std::tm tm = *std::localtime(&dateTime);
    dateString = std::put_time(&tm, "%Y-%m-%e");    //error B: ‘put_time’ is not a member of ‘std’

    //Write out
    std::cout << "date: " << dateString << "\n";

    return 0;
}

1 Ответ

3 голосов
/ 29 мая 2020

C ++ 20 <chrono> все еще находится в разработке для g cc. Я не видел публикации c ETA для этого.

Ваш синтаксис для std::chrono::parse выглядит правильным. Если вы хотите использовать бесплатную предварительную версию C ++ 20 <chrono> с открытым исходным кодом только для заголовков, вы можете заставить ее работать, добавив #include "date/date.h" и используя вместо этого date::parse .

Обратите внимание, что в результате myDate будет 2020-05-24 00:00:00 UT C.

std::put_time находится в заголовке <iomanip> и является манипулятор . После добавления этого заголовка и <iostream> вы должны использовать его следующим образом:

std::cout << "date: " << std::put_time(&tm, "%Y-%m-%e") << '\n';

Если вам нужен вывод в std::string, вам нужно сначала передать манипулятор в std::stringstream.

C ++ 20 <chrono> предоставит альтернативу C API для форматирования:

std::cout << "date: " << std::format("{%Y-%m-%e}", myDate) << '\n';

Библиотека предварительного просмотра также предоставляет это с немного измененным строка формата:

std::cout << "date: " << date::format("%Y-%m-%e", myDate) << '\n';
...