1

私はこのコードを書き留めました。プログラムの私の目的は、2つの指定された日付と時刻の間の分を計算することです。間の分の違いを言うことができます:

14/1/2016 23:18
and
14/1/2004 23:18
is:
6,311,520.00 minutes 

これは私が書いたコードです:

私は計算にいくつかのバグがあります、私が見つけたものから、私の問題は正解と最大で1440分の違いです-Excelによってチェックされました。私の問題は、2つの日付の間のLEAPDAYSの計算にあると思います。

    #include <stdio.h>

    typedef struct {
        int year;
        int month;
        int day;
        int hour;
        int minute;
        int second;     
    }time;
    time time1,time2;

long calcTime(time,time);
int calcDaysFromStart(int,int);
int leapcheck(int);

int main()
{

    printf("Hello\n");
    printf("For calculating the difference between two times:\n");
    printf("Enter the date for first time:\n");
    printf("Enter day:\n");
    scanf("%d",&time1.day);
    printf("Enter month:\n");
    scanf("%d",&time1.month);
    printf("Enter year:\n");
    scanf("%d",&time1.year);
    printf("Enter the exact hour for first time:\n");
    printf("Enter the hour:\n");
    scanf("%d",&time1.hour);
    printf("Enter the minutes:\n");
    scanf("%d",&time1.minute);
    printf("Enter the seconds:\n");
    scanf("%d",&time1.second);
    printf("-----------------------------------\n");
    printf("Enter the date for second time:\n");
    printf("Enter day:\n");
    scanf("%d",&time2.day);
    printf("Enter month:\n");
    scanf("%d",&time2.month);
    printf("Enter year:\n");
    scanf("%d",&time2.year);
    printf("Enter the exact hour for first time:\n");
    printf("Enter the hour:\n");
    scanf("%d",&time2.hour);
    printf("Enter the minutes:\n");
    scanf("%d",&time2.minute);
    printf("Enter the seconds:\n");
    scanf("%d",&time2.second);
    printf("-----------------------------------\n");
    printf("-----------------------------------\n");
    printf("The first time is: %d:%d:%d %d/%d/%d\n", time1.hour ,time1.minute ,time1.second ,time1.day, time1.month ,time1.year);
    printf("The second time is: %d:%d:%d %d/%d/%d\n", time2.hour ,time2.minute ,time2.second ,time2.day, time2.month ,time2.year);
    printf("The Difference between the two times in minutes is:%ld\n", calcTime(time1,time2));
    return 1;   
}


long calcTime(time time1,time time2)
{
    long t1,t2,totalDiff;
    long yearDiffeInMinutes = 0;
    int leapt1, leapt2,leapAdd;
    leapt1 = leapcheck(time1.year);
    leapt2 = leapcheck(time2.year);
    int daysFromStartt1, daysFromStartt2;
    daysFromStartt1 = calcDaysFromStart(time1.month,leapt1);
    daysFromStartt2 = calcDaysFromStart(time2.month,leapt2);
    t1 = time1.minute+time1.hour*60+time1.day*1440+daysFromStartt1*1440;
    t2 = time2.minute+time2.hour*60+time2.day*1440+daysFromStartt2*1440;

    if (time1.year>time2.year)
    {
        leapAdd = (time1.year-time2.year)/4;
        if ((leapt1==1) && (time1.month<3))
            leapAdd--;
        if((leapt2==1) && (time2.month>2))
            leapAdd--;
        printf("THE PARAM leapApp IS:%d\n",leapAdd);
        yearDiffeInMinutes = ((time1.year-time2.year)*525600+leapAdd*1440);
        totalDiff = yearDiffeInMinutes+(t1-t2);
        printf("The first time is bigger\n");
        return totalDiff;
    }
    else if(time2.year>time1.year)
    {
        leapAdd = (time2.year-time1.year)/4;
        if ((leapt2==1) && (time2.month<3))
            leapAdd--;
        if((leapt1==1) && (time1.month>2))
            leapAdd--;
        yearDiffeInMinutes = ((time2.year-time1.year)*525600+leapAdd*1440);
        totalDiff = yearDiffeInMinutes+(t2-t1);
        printf("The second time is bigger\n");
        return totalDiff; 
    }
    else if(t1>t2)/**both times are in the same year**/
    {
        printf("The first time is bigger\n");
        if ((leapt1==1) && (time1.month>2))
            if(time2.month<2)
                return (t1-t2+1440);
        return(t1-t2);
    }
    else if(t2>t1)
    {
        printf("The second time is bigger\n");
        if ((leapt2==1) && (time2.month>2))
            if(time1.month<2)
                return (t2-t1+1440);
        return (t2-t1);
    }
    else
    {
        printf("Both times are equals\n");
        return 0;
    }
}


/**check if the year is leap, return 0 if not a leap and 1 if a leap**/
int leapcheck(int year)
{
    if(year%400==0 || (year%100!=0 && year%4==0))
    {
        printf("THE YEAR %d IS LEAP\n",year);
        return 1;
    }
    printf("THE YEAR %d is NOT LEAP\n",year);
    return 0;
}



/**clalculate how many days past from start ofthe year**/
int calcDaysFromStart(int month, int leap)
{
    if (month==1)
        return 0;
    else if (month==2)
        return 31;
    else if (month==3)
        return (59+leap);
    else if (month==4)
        return (90+leap);
    else if (month==5)
        return (120+leap);
    else if (month==6)
        return (151+leap);
    else if (month==7)
        return (181+leap);
    else if (month==8)
        return (212+leap);
    else if (month==9)
        return (243+leap);
    else if (month==10)
        return (273+leap);
    else if (month==11)
        return (304+leap);
    else if (month==12)
        return (334+leap);
    else return -1;
}
4

3 に答える 3

5

計算

leapAdd = (time1.year-time2.year)/4;

間違っている。2003年から2005年の間にうるう年がありましたが、これはそれを無視します。また、13年のスパンには、世紀の複雑化にぶつかることなく、3年または4年のうるう年を含めることができます。

正しいコードは次のようになります

leapAdd = time1.year/4 - time2.year/4      // how many Caesarian leap years
        - time1.year/100 + time2.year/100  // Centuries
        + time1.year/400 - time2.year/400; // last correction.

(役割が入れ替わっている場合time2.year > time1.year)。

また、

t1 = time1.minute+time1.hour*60+time1.day*1440+daysFromStartt1*1440;

過大評価。月の1日には、追加する完全な日がないため、追加する必要があります。

(time1.day-1)*1440

同様に(time1.hour-1)*60、小児的にも、数分間。ただし、オーバーカウントは一定であるため、時間差の計算には影響しません。

于 2013-01-13T14:25:06.177 に答える
2

これを行うための標準ライブラリ関数があります。

time_t seconds_begin, seconds_end;
struct tm breakdown;

breakdown.tm_year = 2004 - 1900;
breakdown.tm_mon = 0; /* january */
breakdown.tm_mday = 14;
breakdown.tm_hour = 23;
breakdown.tm_min = 18;

seconds_begin = mktime( & breakdown );

breakdown.tm_year = 2016 - 1900;

seconds_end = mktime( & breakdown );

printf( "%.2f minutes", (seconds_end - seconds_begin) / 60. );

https://ideone.com/D8djMo

6311520.00分

Unixシステムでは、これはExcelよりも信頼性が高いと思います。

于 2013-01-13T14:23:44.167 に答える
0

あなたの例の簡単な修正は、 と の両方に次の行を追加することifですelse

if(leapt1==1 && leapt2==1)
    leapAdd++;

しかし、このコードはより大きな間隔 (100 年と 400 年のうるう例外を含む) では失敗します。したがって、コードのこの部分を書き直すことをお勧めします。たとえば、間隔内の各年を反復して、間隔の開始と終了の特別なケーシングを使用して、それが飛躍または共通であるかどうかを確認できます)。

于 2013-01-13T14:16:04.933 に答える