странное поведение mktime в стандартном c - PullRequest
0 голосов
/ 19 октября 2018

С последующим кодом вывод strptime правильный, но mktime полностью выключен, кто-нибудь может мне помочь?

#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <time.h>

int main(void) 
{
    int ddate;
    double dt;
    char dstr1[20],dstr2[20];
    time_t s1,s2;
    struct tm d1,d2;

    strptime("04/06/2015","%m/%d/%Y",&d1); 
    strptime("08/06/2015","%m/%d/%Y",&d2);
    strftime(dstr1,20,"%Y-%m-%d",&d1);
    strftime(dstr2,20,"%Y-%m-%d",&d2); 
    printf("%s,%s\n",dstr1,dstr2);
    s1=mktime(&d1);
    s2=mktime(&d2);
    printf(ctime(&s1));
    printf(ctime(&s2));
    return(0);
}
=== output ====
2015-04-06,2015-08-06
Mon Apr  6 01:51:31 2015
Sun Jan 14 07:16:48 113900

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Описание C11 для mktime равно

Описание

Функция mktime преобразует разбитое время, выраженное как местное время, в структуре, на которую указывает timeptr, в значение календарного времени с той же кодировкой, что и у значений, возвращаемых функцией времени.Исходные значения компонентов tm_wday и tm_yday структуры игнорируются, а исходные значения других компонентов не ограничиваются указанными выше диапазонами. 320) При успешном завершении значенияиз компонентов tm_wday и tm_yday структуры установлены соответствующим образом, а другие компоненты задаются для представления указанного календарного времени, но их значения принудительно устанавливаются в диапазонах, указанных выше;окончательное значение tm_mday не устанавливается до тех пор, пока не будут определены tm_mon и tm_year.

(выделено мной)


Мусор в d1 является причиной.Я написал упрощенную программу:

#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <time.h>

int main(void) {
    time_t s1;
    struct tm d1;

    strptime("04/06/2015","%m/%d/%Y",&d1); 
    printf("%02d:%02d:%02d\n", d1.tm_hour, d1.tm_min, d1.tm_sec);
    s1=mktime(&d1);
    puts(ctime(&s1));
    return(0);
}

Вывод (например)

910751933:01:00
Thu May  8 05:00:01 105913

Т.е. это пятница 19 октября 2018 года в 910751933 часов 1 минута и 0 секунд.

В отличие от mktime, strftime использует только те поля разбитой структуры, которые требуются для формата.

0 голосов
/ 19 октября 2018

Это потому, что d1 и d2 содержат мусор перед вызовом strptime, и это только установка года, месяца и дня struct tm.Таким образом, mktime имеет дело со случайными значениями в других полях как можно лучше.

Добавьте вызов memset или используйте другие средства для очистки содержимого двух переменных, и код работаеткак и ожидалось.

#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>
#include <string.h>
int main () 

    {
    int ddate;
    double dt;
    char dstr1[20],dstr2[20];
    time_t s1,s2;
    struct tm d1,d2;

    memset(&d1,0,sizeof(d1));
    memset(&d2,0,sizeof(d2));
    strptime("04/06/2015","%m/%d/%Y",&d1); 
    strptime("08/06/2015","%m/%d/%Y",&d2);
    strftime(dstr1,20,"%Y-%m-%d",&d1);
    strftime(dstr2,20,"%Y-%m-%d",&d2); 
    printf("%s,%s\n",dstr1,dstr2);
    s1=mktime(&d1);
    s2=mktime(&d2);
    printf("%s",ctime(&s1));
    printf("%s",ctime(&s2));
    return(0);
}
...