2016-10-29 5 views
0

Können Sie mir mit diesem Code helfen? Können Sie erklären, warum Sie in Debian und Openwrt unterschiedliche Ergebnisse mit demselben Code erhalten?C-Code - Zeitfunktionen liefern unterschiedliche Ergebnisse unter Debian Linux und OpenWRT

#include <stdio.h> 
#include <time.h> 
#include <syslog.h> 

int main (void){ 

    char *on_time = "16:45:00"; 
    char *off_time = "19:20:00"; 

    struct tm *tm_on; 
    struct tm *tm_off; 
    struct tm *tm_curr; 

    time_t t_on_time, t_off_time, t_curr_time; 
    time_t t_now, t_now_on, t_now_off; 

    t_now = time (NULL); 
    t_now_on = time(NULL); 
    t_now_off = time (NULL); 

    tm_curr = localtime (&t_now); 
    tm_on = localtime (&t_now_on); 
    tm_off = localtime (&t_now_off); 

    t_curr_time = mktime (tm_curr); 



    syslog (LOG_INFO, "CURRENT TIME IS : %ld is: %s", t_curr_time, ctime (&t_curr_time)); 

    if (sscanf (on_time, "%d:%d:%d", &tm_on->tm_hour, &tm_on->tm_min, &tm_on->tm_sec) == 3) 
    { 

     syslog (LOG_INFO, "TM_ON : %s", asctime(tm_on)); 
     t_on_time = mktime (tm_on); 
     syslog (LOG_INFO, "ON TIME IS  : %ld is: %s", t_on_time, ctime (&t_on_time)); 
    } 


    if (sscanf (off_time, "%d:%d:%d", &tm_off->tm_hour, &tm_off->tm_min, &tm_off->tm_sec) == 3) 
    { 
     syslog (LOG_INFO, "TM_OFF : %s", asctime(tm_off)); 
     t_off_time = mktime (tm_off); 
     syslog (LOG_INFO, "OFF TIME IS  : %ld is: %s", t_off_time, ctime (&t_off_time)); 
    } 

    if (((t_on_time <= t_off_time) && (t_curr_time >= t_on_time) && (t_curr_time <= t_off_time)) || 
     ((t_off_time < t_on_time) && ((t_curr_time <= t_off_time) || (t_curr_time >= t_on_time)))) 
    { 
     printf("SWITCH ON\n"); 
    } 
    else 
    { 
     printf("SWITCH OFF\n"); 
    } 

} 

Ergebnisse in Debian:

Oct 29 18:25:18 s2 helloworld: CURRENT TIME IS : 1477754718 is: Sat Oct 29 18:25:18 2016 
Oct 29 18:25:18 s2 helloworld: TM_ON : Sat Oct 29 16:45:00 2016 
Oct 29 18:25:18 s2 helloworld: ON TIME IS  : 1477748700 is: Sat Oct 29 16:45:00 2016 
Oct 29 18:25:18 s2 helloworld: TM_OFF : Sat Oct 29 19:20:00 2016 
Oct 29 18:25:18 s2 helloworld: OFF TIME IS  : 1477758000 is: Sat Oct 29 19:20:00 2016 

Ergebnisse in OpenWRT:

Oct 29 18:25:25 192.168.11.200 syslog: CURRENT TIME IS : 1477754725 is: Sat Oct 29 18:25:25 2016 
Oct 29 18:25:25 192.168.11.200 syslog: TM_ON : Sat Oct 29 18:25:25 2016 
Oct 29 18:25:25 192.168.11.200 syslog: ON TIME IS  : 1477748700 is: Sat Oct 29 18:25:25 2016 
Oct 29 18:25:25 192.168.11.200 syslog: TM_OFF : Sat Oct 29 18:25:25 2016 
Oct 29 18:25:25 192.168.11.200 syslog: OFF TIME IS  : 1477758000 is: Sat Oct 29 18:25:25 2016 

Wo ist der Fehler? Warum ist OpenWRT anders? Irgendwelche Vorschläge?

+0

vielleicht verwendet man localtime, während die andere UTC verwendet, relevanter Artikel auf arch [wiki] (https://wiki.archlinux.org/index.php/time) – Gmodjackass

+0

Ich hätte auch ein Zeitzonenproblem angenommen, aber Bei Zeitzonenproblemen sind die Daten um einige halbe/volle Stunden verschoben, deins ist, dass es die verschiedenen Eingaben vollständig zu ignorieren scheint und nur die aktuelle Zeit anzeigt. OpenWRT verwendet uClibC, AFAIK, also was ist die Version (benötigte Makros sind hier aufgelistet: https://sourceforge.net/p/predef/wiki/Libraries/)? Aber uClibC ist ziemlich ausgereift, also erwarte ich dort keinen Fehler, aber man weiß nie. – deamentiaemundi

Antwort

0

Was ist Ihre Zeitzone? Ist es zufällig GMT +02: 00, und Sie haben eine Zeitzone auf der Debian-Box, aber nicht auf dem OpenWRT-Router?

Sie können dieses Problem vermeiden, indem Sie localtime() durch gmtime() ersetzen und Ihren gesamten Zeitvergleich bei GMT/UTC wiederholen. Hier

ist ein viel einfacher Beispiel (etwas überarbeitet):

#include <stdio.h> 
#include <time.h> 

int main (void){ 

    struct tm *tm_curr; 
    time_t t_now; 

    t_now = time (NULL); 
    tm_curr = localtime(&t_now); 
    printf("Local: %ld %s", t_now, asctime(tm_curr)); 

    tm_curr = gmtime(&t_now); 
    printf("GMT : %ld %s", t_now, asctime(tm_curr)); 

} 

Ich benutze asctime(), um tatsächlich von den struct tm zu drucken. Sie sehen den Unterschied zwischen Lokalzeit (Zentral für mich und stellte), die die erste Zeile auswirkt, wenn ich es eingestellt (willkürlich) nach Berlin:

[email protected]:/tmp$ ./timeex 
Local: 1477755946 Sat Oct 29 10:45:46 2016 
GMT : 1477755946 Sat Oct 29 15:45:46 2016 
[email protected]:/tmp$ TZ="Europe/Berlin" ./timeex 
Local: 1477755960 Sat Oct 29 17:46:00 2016 
GMT : 1477755960 Sat Oct 29 15:46:00 2016 
[email protected]:/tmp$ 

jedoch die Ergebnisse der gmtime() Anruf wird nicht beeinflusst durch den Wert der TZ und immer was UTC aka GMT ist.

Das wirklich Schlüssel zum Mitnehmen ist, dass time_t ist UTC in beiden Fällen aber struct tm nicht. Sie müssen sich über was Sie sind wo.

Rechnen mit Zeiten und Zeitzonen ist ein Ärger. Im Allgemeinen bevorzuge ich C++ dafür über C, aber es ist gut, dies ein- oder zweimal auf der C-Ebene abzuarbeiten.

+0

Zeitzone sind die gleichen EEST. Wenn Sie Protokolle sehen, ist Epoch gleich, aber das Ergebnis von ctime und asctime sind unterschiedlich. –

+0

Siehe meine erweiterte Antwort mit einem vereinfachten Beispiel. Hoffe das hilft. –

+0

Das Problem ist, dass: 1477748700 ist: Sa 29. Okt 18:25:25 2016 ist nicht richtig. Das ist auf Openwrt, aber die richtige Ausgabe ist das: 1477748700 ist: Sa 29.10. 16:45:00 auf Debian –

Verwandte Themen