C — отсчет минут с определенной даты

#c #pointers #time #count #integer

#c #указатели #время #подсчет #целое число

Вопрос:

Мне нужно подсчитать, сколько минут прошло с определенной даты (1600), но я не всегда получаю ожидаемые результаты.Переменная minutes равна нулю и имеет тип long long int .Например, для даты 2:18 14.10.1900 я представлю 158093418 вместо 158197098 и т. Д.

 #include <stdio.h>
 
int leapYear (int y) {
    if ( y % 4 == 0 amp;amp; ( y % 100 != 0 || y % 400 == 0 ))
        return 1;
    return 0;
}

void zjistiDny (int y, int m, int d, int h, int i, long long int *minutes)
{
    int mesic [13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    long long int days = 0;
    
    for ( int i = 1600; i < y; i   )
    {
        days  = 365;
        if (leapYear(y)){
            days  = 1;
        }

    }
    
    for ( int i = 1; i <m; i  )
    {
        if (i != 2)
        {
            days  = mesic[i];
        }
        else
        {
            if (leapYear(y))
            {
                days  = 1;
            }
            days  = mesic[i];
        } 
    
            
    }

    days  = d;
    *minutes  = days*1440;
    *minutes  = h*60;
    *minutes  = i;
        
}

int main () 
{
    long long int minutes1 = 0, minutes2 = 0, minutes = 0;
    int y1 = 1900, m1= 10, d1 = 14, h1 = 2, i1 = 18;
    int y2 = 1950, m2= 11, d2 = 27, h2 = 6, i2 = 53;
    
    zjistiDny(y1,m1,d1,h1,i1,amp;minutes1);
    zjistiDny(y2,m2,d2,h2,i2,amp;minutes2);
    
    printf("minuty1: %lldn", minutes1);
    printf("minuty1: %lldn", minutes2);
    return 0;
 }
  

Комментарии:

1. У вас есть вариант использования, в котором у вас есть ожидаемое значение и фактическое значение, которые отличаются. Итак, у вас есть хороший способ начать отладку . Пройдитесь по программе, посмотрите на промежуточные результаты и посмотрите, где что-то пошло не так.

2. Вы уверены for ( int i = 1; i <m; i ) , что это то, что вы хотите, а не for ( int i = 0; i <m; i ) ? (индексация равна нулю C .)

3. @Aaron7 Итак, дело в том, что оно не должно быть равным нулю. Что означает ноль? Их нет. Вы просто помещаете его туда, потому что вы индексируете его, начиная с 1 . Но индексация должна начинаться с нуля.

4. Первое if (leapYear(y)) должно быть if (leapYear(i)) связано с тем, что вы подсчитываете дни в каждом промежуточном году в цикле.

5. В этом случае добавьте к вопросу, но, пожалуйста, не меняйте его.

Ответ №1:

2 проблемы в исходном сообщении OP:

Поскольку

Считайте минуты с 1 января 1600 года в 0:00. 1-й день месяца — это ноль дней с начала месяца, а не 1.

 // days  = d;
days  = d - 1;
  

Вызов с индексом года, а не месяца

 // if (leapYear(i)){
if (leapYear(y)){
  

Рекомендуем обнулить minutes zjistiDny() и вернуть минуты

 long long zjistiDny (int y, int m, int d, int h, int i) {
  long long minutes = 0;
  ...
  minutes  = days*1440;
  minutes  = h*60;
  minutes  = i;
  return minutes;
}
  

Альтернативный код, использующий <time.h> и предполагающий time_t , — это секунды с 1970/1/1 0:00:00, и mktime() годен для лет [2000-2399]. Предположим, что григорианский календарь

 #include <time.h>
#define DAYSPER400YEARS (400L * 365   100 - 3)
#define MINSPER400YEARS (DAYSPER400YEARS * 24LL * 60)

long long minutes(int year, int mon, int day, int hour, int min) {
  int year400since2000 = year/400 - 5;
  year = year%400   2000;
  struct tm tm = {0};
  tm.tm_year = year - 1900;
  tm.tm_mon = mon - 1;
  tm.tm_mday = day;
  tm.tm_mday = day;
  tm.tm_hour = hour;
  tm.tm_min = min;
  time_t t = mktime(amp;tm);
  assert(t != -1);
  t /= 60;
  t  = year400since2000 * MINSPER400YEARS;
  return t;
}