2017-10-19 2 views
1

Supposons que je reçois d'un serveur Web une chaîne à analyser. Cette chaîne contient une date au format YYYY-MM-DD. Ce que je veux est de le convertir à l'horodatage qui représente le début de ce jour, donc je ne veux pas de secondes, minutes et heures. Comme exemple factice, j'essaie d'extraire l'horodatage du jour en cours, une fois converti au format YYYY-MM-DD. Voici le code:Parse chaîne de date pour supprimer les heures, minutes et secondes de l'horodatage

#include <chrono>                                                                
#include <iomanip>                                                                
#include <iostream>                                                                
#include <sstream> 
int main() 
{ 
    // Current time at GMT 
    std::time_t now = std::time(0); 
    std::tm *now_tm = std::gmtime(&now); 
    std::ostringstream oss; 
    // Extract yyyy-mm-dd = %F 
    oss << std::put_time(now_tm, "%F"); 
    // Use oss to get a date without seconds from 
    // current time at gmt 
    std::tm tm; 
    std::istringstream ss(oss.str()); 
    ss >> std::get_time(&tm, "%F"); 
    std::time_t current_date = std::mktime(&tm); 
    std::cout << oss.str() << std::endl; 
    std::cout << "cd: " << current_date << std::endl; 
    return 0; 
} 

La sortie est:

2017-10-19 
cd: 1908337984324104 

L'horodatage extrait est manifestement erronée. Où est le problème dans l'analyse de la chaîne 2017-10-19 en utilisant le format %F?

Répondre

1

Le documentation of std::get_time ne répertorie aucun spécificateur de conversion% F. Lors de la vérification de l'indicateur de flux (que vous devriez toujours faire!), Il indiquera également que la conversion a échoué, au moins avec mon compilateur. Donc en le remplaçant par% Y-% m-% d, la conversion réussit. Enfin, vous avez construit par défaut la variable tm sans la mettre à zéro (par exemple, par l'initialisation de la valeur). Lors de la fixation ce ainsi, le code fonctionne comme prévu:

#include <chrono>                                                                
#include <iomanip>                                                                
#include <iostream>                                                                
#include <sstream> 
int main() 
{ 
    // Current time at GMT 
    std::time_t now = std::time(0); 
    std::tm *now_tm = std::gmtime(&now); 
    std::ostringstream oss; 
    // Extract yyyy-mm-dd = %F 
    oss << std::put_time(now_tm, "%Y-%m-%d"); 
    // Use oss to get a date without seconds from 
    // current time at gmt 
    std::tm tm{ }; // value-initialize! 
    std::istringstream ss(oss.str()); 
    ss >> std::get_time(&tm, "%Y-%m-%d"); 
    if(!ss) std::cout << "conversion error\n"; 
    else { 
     std::time_t current_date = std::mktime(&tm); 
     std::cout << current_date << '\n'; 
     std::cout << "cd: " << current_date << '\n'; 
    } 
    return 0; 
} 

http://coliru.stacked-crooked.com/a/d86aa1e1d890a14d

+0

Merci beaucoup! Je regardais la documentation d'une autre fonction de formation du temps, devinant que ce serait la même chose. J'avais tort. – nessuno

1

Vous pouvez le faire sans quitter la sécurité du système de type chrono en utilisant Howard Hinnant's, free, open-source, header-only chrono-extension library.

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

int 
main() 
{ 
    std::istringstream ss{"2017-10-19"}; 
    date::sys_seconds tp; 
    ss >> date::parse("%F", tp); 
    std::cout << date::format("%F\n", tp); 
    using date::operator<<; 
    std::cout << "cd: " << tp.time_since_epoch() << '\n'; 
} 

date::sys_seconds est un std::chrono::time_point qui compte chrono::seconds dans Unix Time. Vous pouvez analyser directement en utilisant %F. Vous pouvez également le formater en utilisant la même chaîne de format (%F) et également inspecter le compte sous-jacent de chrono::seconds. Ce programme produit:

2017-10-19 
cd: 1508371200s 
+0

C'est génial. Merci pour votre suggestion. Garde mon upvote – nessuno