Используйте повышение date_time, чтобы проанализировать и создать даты HTTP

Я пишу своего рода Прокси HTTP, таким образом, я должен смочь сделать 3 вещи:

  1. Проанализируйте дату HTTP, учитывая любой из этих 3 форматов, указанных в RFC 2616, секунда 3.3,
  2. Преобразуйте дату и время файла в строку даты HTTP, и
  3. Произведите дату к строке.

Для ссылки тезисы являются примерами времен даты, которые я должен проанализировать. Я произведу только первый формат:

  Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
  Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
  Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format

Я - вполне уверенное Повышение date_time, может сделать все это, но я испытываю некоторые затруднения из-за номера 1. У кого-либо уже есть код, чтобы сделать это? Возможно, я не использую Google умело, но я не могу найти пример того, как сделать это с повышением где угодно.

Спасибо за любую справку!

ОБНОВЛЕНИЕ: у Меня есть решение, но второй синтаксический анализатор имеет неправильный год (я предполагаю, потому что это - 2 года цифры), и последний синтаксический анализатор дает исключение (см. вывод ниже).

try
{
  // output time now in GMT
  // format we want: Sun, 06 Nov 1994 08:49:37 GMT
  boost::local_time::local_date_time t(boost::local_time::local_sec_clock::local_time(boost::local_time::time_zone_ptr()));
  boost::local_time::local_time_facet* lf(new boost::local_time::local_time_facet("%a, %d %b %Y %H:%M:%S GMT"));
  std::cout.imbue(std::locale(std::cout.getloc(), lf));
  std::cout << t << std::endl;

  // get a file mod time into the correct format
  boost::filesystem::path p("../code/main.cpp");
  boost::posix_time::ptime pt = boost::posix_time::from_time_t(
    boost::filesystem::last_write_time(p));
  boost::local_time::local_date_time t2(pt, boost::local_time::time_zone_ptr());
  std::cout << t2 << std::endl;

  std::stringstream ss;
  ss.exceptions(std::ios_base::failbit);

  // input date-time
  boost::local_time::local_time_input_facet* lif1(new boost::local_time::local_time_input_facet("%a, %d %b %Y %H:%M:%S GMT"));
  ss.imbue(std::locale(std::locale::classic(), lif1));
  ss.str("Sun, 06 Nov 1994 08:49:37 GMT");
  ss >> t;
  std::cout << t << std::endl;

  boost::local_time::local_time_input_facet* lif2(new boost::local_time::local_time_input_facet("%A, %d-%b-%y %H:%M:%S GMT"));
  ss.imbue(std::locale(std::locale::classic(), lif2));
  ss.str("Sunday, 06-Nov-94 08:49:37 GMT");
  ss >> t;
  std::cout << t << std::endl;

  boost::local_time::local_time_input_facet* lif3(new boost::local_time::local_time_input_facet("%a %b %e %H:%M:%S %Y"));
  ss.imbue(std::locale(std::locale::classic(), lif3));
  ss.str("Sun Nov  6 08:49:37 1994");
  ss >> t;
  std::cout << t << std::endl;
}
catch (std::exception& e)
{
  std::cout << "Exception: " << e.what() << std::endl;
}

Вывод:

Sat, 15 May 2010 03:01:13 GMT
Sat, 15 May 2010 03:01:01 GMT
Sun, 06 Nov 1994 08:49:37 GMT
Sat, 06 Nov 2094 08:49:37 GMT
Exception: Parse failed. No match found for ''

5
задан John Price 15 May 2010 в 03:07
поделиться

1 ответ

Вот созданный мной класс DateTime, который выполняет то, что мне нужно. Может еще кто то воспользуется. Этот код в открытом доступе. Я приветствую любые комментарии.

Между прочим, очевидно, что std :: locale принимает указатель на фасет, а затем удаляет его, когда с ним будет работать, поэтому нет необходимости удалять его (на самом деле, его удаление приводит к поломке).

datetime.h:

// $Id$

#ifndef _DATETIME_H_
#define _DATETIME_H_

#include <string>
#include "common.h"
#include <boost/date_time/local_time/local_time.hpp>

class DateTime
{
public:
  DateTime();
  DateTime(const std::string& path);

  // return datetime string
  std::string str();

  // update datetime from file mod date
  std::string from_file(const std::string& path);

  // parse datetime string
  void parse(const std::string& dt);

  // boolean equal operator
  friend bool operator==(const DateTime& left, const DateTime& right);

private:
  boost::local_time::local_date_time m_dt;
};

#endif // _DATETIME_H_

datetime.cpp:

// $Id$

#include <sstream>
#include "common.h"
#include <boost/date_time.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/operations.hpp>
#include "datetime.h"

DateTime::DateTime()
:m_dt(boost::local_time::local_sec_clock::local_time(boost::local_time::time_zone_ptr()))
{
}

DateTime::DateTime(const std::string& path)
:m_dt(boost::local_time::local_sec_clock::local_time(boost::local_time::time_zone_ptr()))
{
  from_file(path);
}

std::string DateTime::str()
{
  std::string result;
  boost::local_time::local_time_facet* lf(new boost::local_time::local_time_facet("%a, %d %b %Y %H:%M:%S GMT"));
  try
  {
    std::stringstream ss;
    ss.imbue(std::locale(ss.getloc(), lf));
    ss << m_dt;
    result = ss.str();
  }
  catch (std::exception& e)
  {
    std::cout << "Exception: " << e.what() << std::endl;
  }
  return result;
}

std::string DateTime::from_file(const std::string& path)
{
  try
  {
    boost::filesystem::path p(path);
    boost::posix_time::ptime pt = boost::posix_time::from_time_t(
      boost::filesystem::last_write_time(p));
    m_dt = boost::local_time::local_date_time(pt, boost::local_time::time_zone_ptr());
  }
  catch (std::exception& e)
  {
    std::cout << "Exception: " << e.what() << std::endl;
  }
  return str();
}

void DateTime::parse(const std::string& dt)
{
  boost::local_time::local_time_input_facet* lif(new boost::local_time::local_time_input_facet("%a, %d %b %Y %H:%M:%S GMT"));
  std::stringstream ss(dt);
  ss.imbue(std::locale(std::locale::classic(), lif));
  ss >> m_dt;
}

bool operator==(const DateTime& left, const DateTime& right)
{
  return (left.m_dt == right.m_dt);
}
4
ответ дан 13 December 2019 в 22:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: