2010-08-04 4 views
5

Ich schreibe eine C++ App, die einen Datum/Uhrzeit-String parsen muss und Epoch Times ausgeben soll. Aber das Format der Datums-/Zeitstring kann mehr als eine sein (tatsächlich sagen, 25 Formate) wieDatums-/Zeitanalyse in C++ (Beliebige Formatzeichenfolge nach Epoche)

"EEE, dd MMM yyyy HH:mm:ss '('ZZZ')'", 
    "EEE, dd MMM yyyy HH:mm:ss '\"'ZZZ'\"'", 
    "EEE, dd MMM yyyy hh:mm:ss z", 
    "EEE, dd MMM yyyy HH:mm Z", 
    "EEE, dd MMM yyyy HH:mm:ss", 
    "EEE, MMM dd, yyyy 'at' HH:mm:ss z", 
    "EEE M/dd/yyyy hh:mm:ss a", 
    "EEE MMM dd HH:mm:ss z yyyy", 
    "EEE MMM dd hh:mm:ss yyyy", 
    "EEEE, MMMM dd, yyyy hh:mm:ss a", 
    "EEEE, MMMM dd, yyyy HH:mm a", 
    "EEEE, MMMM dd, yyyy HH:mm", 
    "MMM dd, yyyy hh:mm:ss a", 
    "dd MMM yyyy hh:mm:ss z", 
    "dd-MMM-yyyy HH:mm:ss z", 
    "dd MMM yy HH:mm:ss", 
    "MM/dd/yyyy hh:mm a (EEEE)", 
    "MM/dd/yyyy hh:mm a (EEEE)", 
    "MM/dd/yyyy hh:mm:ss", 
    "MM/dd/yyyy hh:mm a Z", 
    "MM/dd/yyyy hh:mma Z", 
    "MM/dd/yyyy hh:mma", 
    "MM/dd/yyyy hh:mm a", 
    "MM/dd/yyyy hh:mm Z", 
    "MM/dd/yy hh:mm a Z", 
    "MM/dd/yy hh:mma Z", 
    "MM/dd/yy HH:mm a", 
    "MM/dd/yy HH:mm Z", 
    "MM/dd/yyyy", 
    "yyyy-MM-dd HH:mm:ss", 
    "yyyyMMddhhmmss", 
    "yyyyMMddhhmm", 
    "yyyyMMdd" 

Nun, ich brauche die Zeichenfolge zu nehmen, herauszufinden, es gehört, die dieser Formate, dann bekommen die Zeit in der Epoche.

Können Sie einen Weg vorschlagen, dies zu tun. Codebeispiele werden sehr hilfreich sein. Ich setze auf Boost-Bibliotheken. Lassen Sie mich wissen, ob dies durch Boost-Datum/Zeit-Parsing-Bibliotheken erreicht werden kann.

Vielen Dank im Voraus, AJ

Antwort

13

Ich nehme an, Sie könnten versuchen, die Zeichenfolge in ptime mit jedem dieser Formate zu konvertieren und diejenigen auswählen, die nicht in einem not_a_date_time zur Folge haben.

Die boost format flags sind etwas anders als bei Ihnen, ich werde nur die letzten fünf für dieses Beispiel tun:

#include <iostream> 
#include <boost/date_time/posix_time/posix_time.hpp> 
using boost::posix_time::time_input_facet; 
using std::locale; 
const locale inputs[] = { 
    locale(locale::classic(), new time_input_facet("%m/%d/%Y")), 
    locale(locale::classic(), new time_input_facet("%Y-%m-%d %H:%M:%S")), 
    locale(locale::classic(), new time_input_facet("%Y%m%d%H%M%S")), 
    locale(locale::classic(), new time_input_facet("%Y%m%d%H%M")), 
    locale(locale::classic(), new time_input_facet("%Y%m%d")) }; 
const size_t formats = sizeof(inputs)/sizeof(inputs[0]); 

time_t ptime_to_time_t(boost::posix_time::ptime t) 
{ 
     static boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); 
     return (t-epoch).ticks()/boost::posix_time::time_duration::ticks_per_second(); 
} 
int main() 
{ 
     std::string msg = "2010-08-04 08:34:12"; 

     for(size_t i=0; i<formats; ++i) 
     { 
      std::istringstream ss(msg); 
      ss.imbue(inputs[i]); 
      boost::posix_time::ptime this_time; 
      ss >> this_time; 

      if(this_time != boost::posix_time::not_a_date_time) 
       std::cout << this_time << " or " << ptime_to_time_t(this_time) << std::endl; 
     } 
} 
+0

Dank cubbi für so viel Zeit nehmen, werde ich versuchen, und komme zurück. – AMM

+1

Jetzt sieht es so aus, dass% d und% m 2 Zeichen haben müssen, dh .. es muss wie 01 statt 1 und 05 statt 5 sein. Wie kann ich mit diesem Fall umgehen? Dies scheint ein Problem für mich zu verursachen. Sah auf die Format-Flags konnte nicht viel herausfinden. – AMM

+3

Wenn Ihre Tage und Monate einzelne Ziffern ohne vorangestellte Null oder Leerstelle sein können, können einige dieser Formate nicht eindeutig analysiert werden. Für "yyyyMMdd", würde 2010111 2010-01-11 oder 2010-11-01 sein? Auf jeden Fall, wenn es etwas gibt, was date_time IO nicht verarbeiten kann, gibt es immer boost.spirit. – Cubbi

Verwandte Themen