2010-05-15 15 views
5

que estoy escribiendo una especie de proxy HTTP, así que tengo que ser capaz de hacer 3 cosas:impulsar el uso fecha_hora para analizar y crear HTTP fechas

  1. analizar un HTTP-fecha dada cualquiera de los 3 formatos especificados en RFC 2616, sec 3.3,
  2. Convierta una fecha de archivo a una cadena de fecha HTTP, y
  3. Imprima la fecha en una cadena.

Como referencia, estos son ejemplos de los tiempos de las fechas que necesito analizar. I es la salida sólo el primer formato:

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 

Estoy bastante seguro de fecha_hora Boost puedo hacer todo esto, pero estoy teniendo algunos problemas con el número 1. ¿Alguien ya tiene código para hacer esto? Tal vez no estoy usando Google de forma competente, pero no puedo encontrar un ejemplo de cómo hacerlo con el impulso en cualquier lugar.

¡Gracias por cualquier ayuda!

ACTUALIZACIÓN: Tengo una solución, pero el segundo analizador tiene el año incorrecto (supongo que porque es un año de 2 dígitos) y el último analizador ofrece una excepción (consulte el resultado a continuación).

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; 
} 

Salida:

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 '' 
+1

siempre debe incluir encabezados en la parte superior de su código. esto es para que la gente pueda recoger su código y compilarlo. –

Respuesta

4

Aquí está la clase DateTime creo que hace lo que necesitaba. Quizás alguien más lo use. Este código en el dominio público. Doy la bienvenida a cualquier comentario.

Por cierto, aparentemente std :: locale toma un puntero a una faceta y luego lo elimina cuando termina con él, por lo que no hay necesidad de eliminarlo (de hecho, eliminarlo rompe cosas).

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); 
} 
6

no creo que es necesario ir tan lejos y alcanzar el refuerzo :) Usted puede conseguir lejos con código C simple:

static const char format[] = "%a, %d %b %Y %H:%M:%S %Z"; // rfc 1123 
struct tm tm; 
bzero(&tm, sizeof(tm)); 
if (strptime(str, format, &tm)) {..} 
+3

-1: esto no funciona en Windows. time.h no tiene 'strptime()'. Además, ¿usa C en lugar de Boost? No me gusta eso tampoco. –

Cuestiones relacionadas