Frage

Weiter geht es mein Versuch, eine DateTime-Klasse zu erstellen Ich versuche, die „Epochen“-Zeit in meiner Funktion zu speichern:

void DateTime::processComponents(int month, int day, int year, 
                                 int hour, int minute, int second) {
    struct tm time;
    time.tm_hour = hour;
    time.tm_min = minute;
    time.tm_sec = second;
    time.tm_mday = day;
    time.tm_mon = month;
    time.tm_year = year - 1900;
    ticks_ = mktime(&time);

    processTm(time);
}

void DateTime::processTm(struct tm time) {
    second_ = time.tm_sec;
    minute_ = time.tm_min;
    hour_ = time.tm_hour;
    weekday_ = time.tm_wday;
    monthday_ = time.tm_mday;
    yearday_ = time.tm_yday;
    month_ = time.tm_mon;
    year_ = time.tm_year + 1900;
}

Für ein beliebiges Datum, processComponents(5,5,1990,1,23,45) (6. Juni 1990, 1:23:45 Uhr) werden alle Werte korrekt und wie erwartet eingestellt.

Bei weiteren Tests stelle ich jedoch fest, dass dies der Fall ist processComponents(0,0,1970,0,0,0) (1. Januar 1970, 00:00:00 Uhr), mktime(&time) Ursachen time vermasselt werden:

time.tm_mon  = 11;
time.tm_mday = 30;
time.tm_year = 69;
time.tm_hour = 23;
time.tm_min  = 0;
time.tm_sec  = 0;

time.tm_isdst  = 0;
time.tm_gmtoff = -18000;
time.tm_zone   = "EST";
time.tm_wday   = 2;
time.tm_yday   = 363;

Übertragen auf das Datum 31. Dezember 1969, 23:00:00 Uhr.

Das kann ich bestätigen mktime() ist dafür verantwortlich, denn durch das Auskommentieren dieser Zeile werden Datum und Uhrzeit korrekt als 1. Januar 1970, 12:00:00 Uhr gemeldet.

Warum ist mktime() Nur die Epoche vermasseln?Und wie soll ich das beheben/umgehen?

Danke!

War es hilfreich?

Lösung

Sie übergeben 0 als day Parameter und fügen Sie ihn ein time.tm_mday.Diese Komponente (und nur diese Komponente) von struct tm ist 1-basiert, nicht 0-basiert.

Frag mich nicht warum.

Um den 01. Januar 1970, 00:00:00 Uhr anzugeben, möchten Sie ihn folgendermaßen nennen:

processComponents(0,1,1970,0,0,0);

Und wie sdtom erwähnt, das sollten Sie sicherstellen tm_isdst ist entsprechend eingestellt – 0 für nicht wirksam, positiv für wirksam und negativ für Sie wissen es nicht (in diesem Fall). mktime() sollte versuchen zu erraten).

Nur um Sie wissen zu lassen, wann ich das von Ihnen angegebene Datum (0. Januar 1970, 00:00:00) überschritten habe mktime() In MSVC 9 wird ein Fehler zurückgegeben (der übergebene Fehler). struct tm ist unberührt und wird zurückgegeben time_t Wert ist -1).

Andere Tipps

Da es um eine Stunde schmeckt, würde ich bei der Tageslichtsparungszeit rechnen. Ist der Wert der Zeit.tm_isdst irgendwo festgelegt? Wenn Sie es nicht festlegen, kann es zufällig auf 1 oder 0 eingestellt werden, was sich auf Ihre Ergebnisse auswirken würde.

Alle Nullen an weitergeben mktime() wird als "Sonne Jan 0 00:00:00 1900" interpretiert. Basierend darauf müssen einige Anpassungen bestehen ...

// the input is local time
// the output is seconds since the epoch
// The epoch is Jan 1, 1970 @ 0:00 GMT
time_t mktime_wrapper( int month, int day, int year,
                       int hour=0, int min=0, int sec=0, bool isDST=-1
                     )
   {
   tm t;
   t.tm_sec=sec, t.tm_min=min, t.tm_hour=hour, t.tm_isdst=isDST;
   t.tm_mday=day, t.tm_mon=month-1, t.tm_year=year-1900;
   return mktime( &t );
   }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top