Как преобразовать дд-ммм-гггг и сейчас() в дни?

Мне нужно преобразовать строку dd-mmm-year в дни эпохи, чтобы выполнить простую математику. В частности, подсчитайте количество дней с now() до даты строки.

Я смотрю на <chrono> и <ctime>, но не вижу очевидного способа сделать это? Как вы конвертируете dd-mmm-year и now() в дни эпохи?


person buttonsrtoys    schedule 25.03.2021    source источник
comment
Отвечает ли это на ваш вопрос? Использование momentjs для преобразования даты в эпоху, а затем обратно в дата   -  person Ali Al Amine    schedule 25.03.2021
comment
epoch days дней с начала эпохи? Т.е. секунды с начала эпохи, разделенные на секунды в сутках?   -  person KamilCuk    schedule 26.03.2021


Ответы (1)


Это легко сделать с помощью этой бесплатной предварительной версии C++20 с открытым исходным кодом, состоящей только из заголовков , который работает с С++ 14.11.17:

#include "date/date.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;

    string s1 = "25-Mar-2021";
    string s2 = "20-Jul-2021";
    istringstream in{s1};
    in.exceptions(ios::failbit);
    sys_days t1;
    in >> parse("%d-%b-%Y", t1);
    in.str(s2);
    in.clear();
    sys_days t2;
    in >> parse("%d-%b-%Y", t2);
    cout << t2 - t1 << '\n';
}

sys_days — это псевдоним типа std::chrono::time_point<system_clock, duration<int, ratio<86400>>>. Но вы можете думать об этом как о количестве дней с 1 января 1970 года.

Программа выше выводит:

117d

Тип выражения t2 - t1std::chrono::duration<int, ratio<86400>>.

Вот живой пример, с которым вы можете поэкспериментировать.

Редактировать:

Вы можете преобразовать длительности (например, t2 - t1) в целочисленный тип со знаком, используя функцию-член .count():

auto i = (t2 - t1).count();  // 117

Другой способ сделать это — разделить на days{1}:

auto i = (t2 - t1)/days{1};  // 117

Этот последний метод дает тем, кто знаком с анализом размерностей, теплое ощущение нечеткости. :-)

Вы можете преобразовать std::chrono::system_clock::now() в тип sys_days следующим образом:

auto t2 = floor<days>(system_clock::now());

Это дает текущую дату в соответствии с UTC. Если вам нужна текущая дата в соответствии с каким-либо другим часовым поясом (например, в соответствии с настройками локального часового пояса компьютера), то для этого требуется дополнительная библиотека (по той же ссылке), которая не является только заголовком и требует некоторая установка. В этом случае можно было бы работать с точки зрения local_days вместо sys_days:

#include "date/tz.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;

    string s1 = "25-Mar-2021";
    istringstream in{s1};
    in.exceptions(ios::failbit);
    local_days t1;
    in >> parse("%d-%b-%Y", t1);
    auto t2 = floor<days>(current_zone()->to_local(system_clock::now()));
    cout << t2 - t1 << '\n';
}

Выход (в настоящее время):

1d
person Howard Hinnant    schedule 25.03.2021
comment
Спасибо @Говард. Похоже, как раз то, что мне нужно. t2 - t1 приводит к типу date::days — как преобразовать его в int? Кроме того, не могли бы вы изменить свой пример, чтобы сделать s2 равным now(), как я упоминал в своем OP? Мне нужно рассчитать с сегодняшнего дня до указанной даты. - person buttonsrtoys; 26.03.2021
comment
@buttonsrtoys: Обновлено. - person Howard Hinnant; 26.03.2021
comment
Я думаю, что нужен звонок locale("LC_ALL=C"). - person KamilCuk; 26.03.2021
comment
Только если вы хотите убедиться, что аббревиатуры названий месяцев C читаются, и вы установили глобальное локальное значение на что-то другое. В качестве альтернативы вы можете заполнить in желаемой локалью и избежать глобальных настроек. - person Howard Hinnant; 26.03.2021