Как я могу получить вчерашнюю дату в C? - PullRequest
3 голосов
/ 20 января 2011

Я хочу получить вчерашнюю дату в символ в формате: ГГГГММДД (без косых черт и т. Д.).

Я использую этот код для получения сегодняшней даты:

time_t now;

struct tm  *ts;  
char yearchar[80]; 

now = time(NULL);  
ts = localtime(&now);

strftime(yearchar, sizeof(yearchar), "%Y%m%d", ts);

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

Большое спасибо.

Ответы [ 7 ]

8 голосов
/ 21 января 2011

Функция mktime() нормализует struct tm, который вы передаете, поэтому все, что вам нужно сделать, это:

now = time(NULL);
ts = localtime(&now);
ts->tm_mday--;
mktime(ts); /* Normalise ts */
strftime(yearchar, sizeof(yearchar), "%Y%m%d", ts);
5 голосов
/ 20 января 2011

как насчет добавления

now = now - (60 * 60 * 24)

Может произойти сбой в некоторых ОЧЕНЬ редких угловых случаях (например, в течение секунд), но должно делать то, что вы хотите, 99,999999% времени.

2 голосов
/ 24 января 2013

Пожалуйста, попробуйте этот код

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
 
int main(void)
{
    char yestDt[9];
    time_t now = time(NULL);
    now = now - (24*60*60);
    struct tm *t = localtime(&now);
    sprintf(yestDt,"%04d%02d%02d", t->tm_year+1900, t->tm_mday,t->tm_mon+1);
    printf("Target String: \"%s\"", yestDt);
    return 0;
}
2 голосов
/ 20 января 2011

Нужно просто вычесть значение одного дня из секунд из time(NULL);. Измените эту строку:

now = time(NULL);

к этому:

now = time(NULL) - (24 * 60 * 60);
0 голосов
/ 20 января 2011
time_t now;
int day;

struct tm  *ts;  
char yearchar[80]; 

now = time(NULL);  
ts = localtime(&now);
day = ts->tm_mday;

now = now + 10 - 24 * 60 * 60;
ts = localtime(&now);
if (day == ts->tm_mday)
{
  now = now - 24 * 60 * 60;
  ts = localtime(&now);
}

strftime(yearchar, sizeof(yearchar), "%Y%m%d", ts);

Будет работать и с високосными секундами.

0 голосов
/ 20 января 2011

Вы можете манипулировать содержимым структуры ts перед передачей его в strftime.День месяца содержится в элементе tm_mday.Основная процедура:

/**
 * If today is the 1st, subtract 1 from the month
 * and set the day to the last day of the previous month
 */
if (ts->tm_mday == 1)
{
  /**
   * If today is Jan 1st, subtract 1 from the year and set
   * the month to Dec.
   */
  if (ts->tm_mon == 0)
  {
    ts->tm_year--;
    ts->tm_mon = 11;
  }
  else
  {
    ts->tm_mon--;
  }

  /**
   * Figure out the last day of the previous month.
   */
  if (ts->tm_mon == 1)
  {
    /**
     * If the previous month is Feb, then we need to check 
     * for leap year.
     */
    if (ts->tm_year % 4 == 0 && ts->tm_year % 400 == 0)
      ts->tm_mday = 29;
    else
      ts->tm_mday = 28;
  }
  else
  {
    /**
     * It's either the 30th or the 31st
     */
    switch(ts->tm_mon)
    {
       case 0: case 2: case 4: case 6: case 7: case 9: case 11:
         ts->tm_mday = 31;
         break;

       default:
         ts->tm_mday = 30;
    }
  }
}
else
{
  ts->tm_mday--;
}

Редактировать: Да, дни месяца нумеруются с 1, тогда как все остальное (секунды, минуты, часы, рабочие дни и дни года) нумеруются с 0.

0 голосов
/ 20 января 2011

Ты довольно близко. Прежде всего, решение Тайлера будет работать почти - вам нужно использовать (24*60*60*1000), поскольку time (3) возвращает миллисекунды . Но взгляните на это struct tm. В нем есть поля для всех компонентов даты.

Обновление: Черт, моя ошибка - время (3) возвращает секунды. Я думал о другом звонке. Но все равно посмотрите на содержимое struct tm.

...