2008-11-26 50 views

Respuesta

18

Use strptime() para analizar el tiempo en un struct tm, luego use mktime() para convertirlo a time_t.

+0

strptime() no parece estar disponible en Windows. ¿Hay una buena alternativa? –

+0

No sé si una buena alternativa en Windows, hay varias implementaciones de código abierto flotando que podría usar. Alternativamente, si sabe que la fecha siempre estará en el formato que proporcionó, puede analizarla en una estructura tm, tal vez usando sscanf, y luego usar mktime para obtener un time_t. –

+0

aquí hay un ejemplo http://stackoverflow.com/a/11213640/1115059 – Jaydeep

2

Me temo que no hay ninguno en el estándar C/C++. Existe la función POSIX strptime que se puede convertir a struct tm, que luego se puede convertir a time_t usando mktime.

Si está buscando la compatibilidad multiplataforma, mejor use boost::date_time, que tiene funciones sofisticadas para esto.

4

En ausencia de strptime podría utilizar sscanf para analizar los datos en un struct tm y luego llamar mktime. No es la solución más elegante, pero funcionaría.

+1

Gracias Rob ... buena foto por cierto. –

-1
static time_t MKTimestamp(int year, int month, int day, int hour, int min, int sec) 
{ 
    time_t rawtime; 
    struct tm * timeinfo; 

    time (&rawtime); 
    timeinfo = gmtime (&rawtime); 
    timeinfo->tm_year = year-1900 ; 
    timeinfo->tm_mon = month-1; 
    timeinfo->tm_mday = day; 
    timeinfo->tm_hour = hour; 
    timeinfo->tm_min = min; 
    timeinfo->tm_sec = sec; 
    timeinfo->tm_isdst = 0; // disable daylight saving time 

    time_t ret = mktime (timeinfo); 

    return ret; 
} 

static time_t GetDateTime(const std::string pstr) 
{ 
    try 
    { 
     // yyyy-mm-dd 
     int m, d, y, h, min; 
     std::istringstream istr (pstr); 

     istr >> y; 
     istr.ignore(); 
     istr >> m; 
     istr.ignore(); 
     istr >> d; 
     istr.ignore(); 
     istr >> h; 
     istr.ignore(); 
     istr >> min; 
     time_t t; 

     t=MKTimestamp(y,m,d,h-1,min,0); 
     return t; 
    } 
    catch(...) 
    { 

    } 
} 
1

Tenga en cuenta que strptime mencionado en respuesta aceptada no es portátil. Aquí está la mano de código C++ 11 utilizo para convertir cadena a std :: time_t:

static std::time_t to_time_t(const std::string& str, bool is_dst = false, const std::string& format = "%Y-%b-%d %H:%M:%S") 
{ 
    std::tm t = {0}; 
    t.tm_isdst = is_dst ? 1 : 0; 
    std::istringstream ss(str); 
    ss >> std::get_time(&t, format.c_str()); 
    return mktime(&t); 
} 

se le puede llamar así:

std::time_t t = to_time_t("2018-February-12 23:12:34"); 

puede encontrar parámetros de formato de cadena de here.

+0

1) El código no establece el miembro 'tm_isdst'. No hacerlo puede generar resultados inconsistentes.2) 'struct tm' no permite miembros adicionales que se beneficien con la inicialización. Quizás 'std :: tm t = {0};'? 3) La cadena del mes de OP es numérica, no alfa, Use '"% m "' en lugar de '"% b "'. 4) OP utilizó un orden diferente a YMD hms. – chux

+0

Agregué la opción dst. Init con 0 es una buena idea. Otras cosas se pueden ajustar fácilmente como requisitos individuales. – ShitalShah

1

mejor manera de convertir una cadena de fecha, el formato "MM-DD-AA HH: MM: SS", a un time_t

La restricción de código para funciones de la biblioteca estándar de C está buscando a la inversa de strftime(). Para ampliar @Rob idea general, utiliza sscanf().

Uso "%n" para detectar escaneo completado

time_t date_string_to_time(const char *date) { 
    struct tm tm = { 0 }; // Important, initialize all members 
    int n = 0; 
    sscanf(date, "%d-%d-%d %d:%d:%d %n", &tm.tm_mon, &tm.tm_mday, &tm.tm_year, 
     &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &n); 
    // If scan did not completely succeed or extra junk 
    if (n == 0 || date[n]) { 
    return (time_t) -1; 
    } 
    tm.tm_isdst = -1; // Assume local daylight setting per date/time 
    tm.tm_mon--;  // Months since January 
    // Assume 2 digit year if in the range 2000-2099, else assume year as given 
    if (tm.tm_year >= 0 && tm.tm_year < 100) { 
    tm.tm_year += 2000; 
    } 
    tm.tm_year -= 1900; // Years since 1900 
    time_t t = mktime(&tm); 
    return t; 
} 

código adicional se podría utilizar para asegurar sólo 2 partes de dígitos de marca de tiempo, los valores positivos, espaciado, etc.

Nota: Esta asumir la "MM-DD -YY HH: MM: SS "es un local tiempo.

+1

Interesante, nunca encontré un caso de uso para '% n' ya que siempre utilicé el valor de retorno de' * scanf' para asegurarme de que todos los argumentos fueron escaneados. Sin embargo, aparece '% n' (la forma en que lo usa) esto * y * asegura que no hay gumpf adicional siguiendo la cadena esperada. No es frecuente que aprenda algo nuevo sobre C hoy en día, así que felicitaciones :-) – paxdiablo

+1

@paxdiablo Gracias. El '"% n "', en general, ayuda a detectar cualquier texto final requerido, algo que el valor de retorno no distingue. P.ej. '"% d xyz% n "'. – chux