strftime не указывает год структуры tm

У меня есть эта функция, которая получает день до даты ввода:

Date dateDayBefore(char* inputDate)
{
     struct tm dayBefore = { 0 };

     char** fields = split(inputDate, 3, "/");

     dayBefore.tm_mday = atoi(fields[0]);
     dayBefore.tm_mon = atoi(fields[1]) - 1;
     dayBefore.tm_year = atoi(fields[2]) - 1900;

     dayBefore.tm_mday--;
     mktime(&dayBefore);

     char yesterday[10];
     strftime(yesterday, sizeof(yesterday), "%d/%m/%Y", &dayBefore);

     Date yesterdayDate = dateCreate(yesterday);
     yesterdayDate.year += 1900;
     return yesterdayDate;
}

Предположим, что все другие используемые функции верны (такие как split и dateCreate), они используются в других местах, где все так, как ожидалось.

struct dayBefore будет содержать год, но string yesterday не будет рассматривать его после strftime

Для: inputDate = 15.06.2020

ожидаемый результат: 06.14.2020

фактический результат: 14.06.1900

Несколько скриншотов отладки:

введите здесь описание изображениявведите здесь описание изображения


person walkman    schedule 15.06.2020    source источник
comment
Что такое dateCreate? Ваша проблема связана с тем, что yesterday является локальным для функции? Предоставьте минимальную, запускаемую демонстрацию проблемы. (См. минимально воспроизводимый пример)   -  person ikegami    schedule 15.06.2020
comment
Нет, проблема внутри прицела. dateCreate получает строку и возвращает структуру с целыми числами в виде дня, месяца, года. Все работает как положено @ikegami   -  person walkman    schedule 15.06.2020
comment
Предоставьте минимальную, работоспособную демонстрацию проблемы, если требуется. (См. минимально воспроизводимый пример)   -  person ikegami    schedule 15.06.2020
comment
Используйте strptime и не выполняйте собственные расчеты даты. Календари безумно странные. Разберите время на struct tm, установите часы, минуты и секунды на 0. Создайте time_t, используя mktime, вычтите несколько минут, преобразуйте обратно в struct tm.   -  person Cheatah    schedule 15.06.2020
comment
char yesterday[10]; недостаточно большой. Вы забыли учесть NUL.   -  person ikegami    schedule 15.06.2020
comment
@Cheetah, я тоже не уверен, что это сработает. mktime использует местное время, и не все дни имеют 00:00:00 во всех часовых поясах. (Ссылка) Если вы сначала установите TZ в UTC, это сработает.   -  person ikegami    schedule 15.06.2020
comment
@ikegami, черт возьми, нуб... спасибо! если вы хотите опубликовать ответ, я приму его как правильный   -  person walkman    schedule 15.06.2020


Ответы (1)


Вы пытаетесь сохранить 10-символьную строку (14/06/2020) в 10-символьном массиве, в котором нет места для NULL.

Заменять

char yesterday[10];

с участием

char yesterday[11];

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


Ваш вопрос содержит много не относящихся к делу деталей. Вы можете продемонстрировать проблему, используя следующее:

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

int main(void) {
   char* fields[] = { "15", "06", "2020" };

   dayBefore.tm_mday = atoi(fields[0]);
   dayBefore.tm_mon = atoi(fields[1]) - 1;
   dayBefore.tm_year = atoi(fields[2]) - 1900;

   dayBefore.tm_mday--;
   mktime(&dayBefore);

   char yesterday[10];
   strftime(yesterday, sizeof(yesterday), "%d/%m/%Y", &dayBefore);
   printf("%s\n", yesterday);
}
person ikegami    schedule 15.06.2020
comment
Большое спасибо, решение сработало, и я буду более осторожен и точен, демонстрируя вопрос в будущем! - person walkman; 15.06.2020