конвертировать данные / время в tm / time_point против musl и glibc. Общий способ

Я хотел бы преобразовать строковые данные в struct tm (с) или std::chrono::time_point, Проблема в том, что я хочу рабочее решение для обеих стандартных библиотек libc (glibc и MUSL). У меня есть стандартные форматы дерева, которые я хочу разобрать.

  1. RFC-1123

    Воскресенье, 06 ноября 1994 08:49:37 GMT

  2. RFC-850

    «Воскресенье, 06 ноября-94 08:49:37 по Гринвичу»

  3. ANSI C в формате asctime

    Вс 6 ноября 08:49:37 1994 «

Есть ли способ заставить его работать? std::get_time имеет ошибка
strptime отлично работает (и быстро) на glibc, но не работает против musl.

Любая идея? Я не хочу использовать поток, как в get_time, Но если бы это было необходимо, то хорошо. (Можно использовать стандарт GCC5> и c ++ 11)

2

Решение

Бесплатная библиотека Говарда Хиннанта с открытым исходным кодом, только заголовки, дата / время можно проанализировать эти форматы в std::chrono::time_pointдаже в контексте неисправного get_time а также strptime объекты. Это требует использования std::istringstream хоть. Вот как это выглядит:

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

std::chrono::system_clock::time_point
parse_RFC_1123(const std::string& s)
{
std::istringstream in{s};
std::chrono::system_clock::time_point tp;
in >> date::parse("%a, %d %b %Y %T %Z", tp);
return tp;
}

std::chrono::system_clock::time_point
parse_RFC_850(const std::string& s)
{
std::istringstream in{s};
std::chrono::system_clock::time_point tp;
in >> date::parse("%a, %d-%b-%y %T %Z", tp);
return tp;
}

std::chrono::system_clock::time_point
parse_asctime(const std::string& s)
{
std::istringstream in{s};
std::chrono::system_clock::time_point tp;
in >> date::parse("%a %b %d %T %Y", tp);
return tp;
}

Это можно осуществить так:

#include <iostream>

int
main()
{
auto tp = parse_RFC_1123("Sun, 06 Nov 1994 08:49:37 GMT");
using namespace date;
std::cout << tp << '\n';
tp = parse_RFC_850("Sunday, 06-Nov-94 08:49:37 GMT");
std::cout << tp << '\n';
tp = parse_asctime("Sun Nov 6 08:49:37 1994");
std::cout << tp << '\n';
}

и выводы:

1994-11-06 08:49:37.000000
1994-11-06 08:49:37.000000
1994-11-06 08:49:37.000000

Флаги разбора %a а также %b обычно зависят от локали. Однако, если вы скомпилируете эту библиотеку с -DONLY_C_LOCALE=1 это становится независимый от региона. Это должен дать тот же результат в любом случае. Но с практической точки зрения, если вы компилируете без -DONLY_C_LOCALE=1 и вы не получите результатов выше, вы должны отправить отчет об ошибке вашему поставщику std :: lib.

Если вы компилируете с -DONLY_C_LOCALE=1 и вы не получите результаты выше, погремите моей клетке, и я исправлю это в течение нескольких дней, если не часов.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]