close
之前寫過的C的題目

 aaaa

輸入一個參數 為秒數,顯示距離1970年1月1號00:00:00的日期與時間,可輸入負數

寫出來讓大家參考。

EX:

[root@linux CalDateForm]# ./CalDateForm 10
1970-01-01 (Thur.)    00:00:10
[root@linux CalDateForm]# ./CalDateForm -10
1969-12-31 (Wed.)    23:59:50 
++++++++++++++++++++++++++++++++++++++++

#include
#include
//#include

#define DEBUG 0
const long LONG_MUL_MIN = -2147483647;
const long LONG_MAX     = 2147483647;

const int NonLeapMonth[12] ={31,28,31,30,31,30,31,31,30,31,30,31};
const int LeapMonth[12]    ={31,29,31,30,31,30,31,31,30,31,30,31};

const char Week[7][7]          ={"Mon.","Tues.","Wed.","Thur.",
                                               "Fir.","Sta.","Sun."};

//時間的結構
struct Date
{
    int iYear;
    int iMonth;
    int iDay;
    int iWeek;
    int iHour;
    int iMin;
    int iSecond;
};
//判斷是否為閏年
int IsLeapYear(const int iInputYear)
{
    if ( 0 == iInputYear % 400)
    {
        return 1;
    }
    else if ( 0 == iInputYear % 100)
    {
        return 0;
    }
    else if ( 0 == iInputYear % 4)
    {
        return 1;
    }
    return 0;
}
//檢查時間格式
void CheckDateForm(const struct Date datInputDate)
{
    
    if ((datInputDate.iMonth > 12) ||(datInputDate.iMonth <= 0 ))
    {//判斷月份有誤
        printf("時間格式:[月份]有誤,無法判斷[日期]格式:是否超過月份天數\n");
    }
    else
    {//判對月份無誤
        if (1 == IsLeapYear(datInputDate.iYear))
        {//判斷為閏年
            if (datInputDate.iDay > LeapMonth[(datInputDate.iMonth -1)] )
            {
                printf("時間格式:[日期]超過月份天數\n");
            }
        }
        else
        {//判斷不為閏年
            if (datInputDate.iDay > NonLeapMonth[(datInputDate.iMonth -1)]  )
            {
                printf("時間格式:[日期]超過月份天數\n");
            }
        }
    }
    if (datInputDate.iDay < 1)
    {
        printf("時間格式:[日期]小於1\n");
    }
    
    
    if ((datInputDate.iHour > 23) ||(datInputDate.iHour < 0 ))
    {
        printf("時間格式:[小時]有誤\n");
    }
    if ((datInputDate.iMin > 59) ||(datInputDate.iMin < 0 ))
    {
        printf("時間格式:[分鐘]有誤\n");
    }
    if ((datInputDate.iSecond > 59) ||(datInputDate.iSecond < 0 ))
    {
        printf("時間格式:[秒鐘]有誤\n");
    }

    if ((datInputDate.iWeek > 6) ||(datInputDate.iWeek < 0 ) )
    {
        printf("時間格式:[星期]有誤\n");
    }
}
//將時間結構的內容印出
void PrintDate(const struct Date datOutputDate)
{
    printf("%d-%02d-%02d (%s)    %02d:%02d:%02d\n",
        datOutputDate.iYear,datOutputDate.iMonth,datOutputDate.iDay,
        Week[datOutputDate.iWeek],
        datOutputDate.iHour,datOutputDate.iMin,datOutputDate.iSecond);
    CheckDateForm(datOutputDate);
}
//將時間結構內容初始化 [1970-01-01 00:00:00]
void InitDate( struct Date* datOutputDate)
{
    datOutputDate->iYear    = 1970;
    datOutputDate->iMonth   = 1;
    datOutputDate->iDay     = 1;
    datOutputDate->iHour    = 0;
    datOutputDate->iMin     = 0;
    datOutputDate->iSecond  = 0;
}
//計算輸入年份 回傳當年的天數
int CalYearDay (const int iInputYear)
{
    int iLeapYearDays = 366;
    int iNonLeapYearDays = 365;
    

    if ( 0 == IsLeapYear(iInputYear) )
    {//判斷不為閏年
         return iNonLeapYearDays;
    }
    //判斷為閏年
    return  iLeapYearDays;
    

}

//計算輸入的天數 回傳年份 並將不足一年的天數保留
int CalYear(int* iDiffday)
{
    int iThisYear = 1970;
    int iThisYearDays = 0;

    iThisYearDays = CalYearDay(iThisYear);

    while (*iDiffday >= iThisYearDays)
    {
        *iDiffday -= iThisYearDays;
        iThisYear++;
        iThisYearDays = CalYearDay(iThisYear);
    }
    if (*iDiffday < 0)
    {
        return -1;
    }
    return iThisYear;

}
//計算輸入的天數 回傳月份 並將不足一月的天數保留
int CalMonth(int* iDiffday,const int iThisYear)
{
    int iIndexMonth =0;
    if ( 0 == IsLeapYear(iThisYear) )
    {//判斷不為閏年
        while ( *iDiffday >= NonLeapMonth[iIndexMonth]   )
        {
            *iDiffday -= NonLeapMonth[iIndexMonth];
            iIndexMonth++;
        }

    }
    else
    {//判斷為閏年
        while ( *iDiffday >= LeapMonth[iIndexMonth]   )
        {
            *iDiffday -= LeapMonth[iIndexMonth];
            iIndexMonth++;
        }

    }
    return iIndexMonth+1;  

}
//計算 在 [1970-01-01  00:00:00] 之後 所差距的日期 
void CalDateDiff(struct Date* datOutputDate,const int iDiffday,const int iDiffHour,
            const int iDiffMin,const int iDiffsecond)
{
    
    datOutputDate->iDay     += iDiffday;
    datOutputDate->iHour    += iDiffHour;
    datOutputDate->iMin     += iDiffMin;
    datOutputDate->iSecond  += iDiffsecond;

}
///////////////////////////////////////////---------------------

//計算輸入的時間範圍在 [1970-01-01  00:00:00] 之前
//計算輸入的天數 回傳差距的月數 並將不足一月的天數保留
int CalRevDiffMonth(int* iDiffday,const int iThisYear)
{
    int iDiffMonth  = 0;
    int iIndexMonth = 11;

    if ( 0 == IsLeapYear(iThisYear) )
    {//判斷不為閏年
        while ( *iDiffday >= NonLeapMonth[iIndexMonth]   )
        {
            *iDiffday -= NonLeapMonth[iIndexMonth];
            iIndexMonth--;
            iDiffMonth++;
        }

    }
    else
    {//判斷為閏年
        while ( *iDiffday >= LeapMonth[iIndexMonth]   )
        {
            *iDiffday -= LeapMonth[iIndexMonth];
            iIndexMonth--;
            iDiffMonth++;
        }

    }
    return iDiffMonth;

}
////////////////////////////////******
//計算輸入的時間範圍在 [1970-01-01  00:00:00] 之前
//計算輸入的天數 回傳差距的年數 並將不足一年的天數保留
int CalRevDiffYear(int* iDiffday)
{
    int iDiffYear = 0;
    int iThisYearDays = 0;
    int iThisYear = 1969;//從1969年開始
    
    iThisYearDays = CalYearDay(iThisYear);

    while (*iDiffday >= iThisYearDays)
    {
        *iDiffday -= iThisYearDays;
        iThisYear--;
        iDiffYear++;
        iThisYearDays = CalYearDay(iThisYear);
    }

    if (*iDiffday < 0)
    {//計算天數錯誤
        return -1;
    }
    return iDiffYear;

}

////////////////////////////////*****
//計算 在 [1970-01-01  00:00:00] 之前 所差距的日期 
void CalRevDateDiff(struct Date* datOutputDate,const int iDiffYear,const int iDiffMonth,const int iDiffDay,
               const int iDiffHour,const int iDiffMin,const int iDiffsecond)
{
    datOutputDate->iYear    -= iDiffYear;
    datOutputDate->iMonth   -= iDiffMonth;
    if (0 >= datOutputDate->iMonth )
    {
        datOutputDate->iYear--;
        datOutputDate->iMonth +=12;
    }
    datOutputDate->iDay     -= iDiffDay;

    if ( 0 >= (datOutputDate->iDay) )//判斷日期是否小於或等於零
    {//借位
        datOutputDate->iMonth -=1;
        if ( 0 >= (datOutputDate->iMonth) )//判斷月份是否小於或等於零
        {//借位
            datOutputDate->iYear -=1;
            datOutputDate->iMonth += 12;
        }
        if ( 0 == IsLeapYear(datOutputDate->iYear) )
        {//判斷不為閏年
            datOutputDate->iDay += NonLeapMonth[datOutputDate->iMonth-1];
        }
        else
        {//判斷為閏年
            datOutputDate->iDay += LeapMonth[datOutputDate->iMonth-1];
        }        
    }
    /////////////////////////////////////////
    datOutputDate->iHour    -= iDiffHour;
    datOutputDate->iMin     -= iDiffMin;
    datOutputDate->iSecond  -= iDiffsecond;
    
    if ( 0 > (datOutputDate->iSecond ) )
    {////借位
        datOutputDate->iMin -= 1;
        datOutputDate->iSecond +=60;
    }
    if ( 0 > (datOutputDate->iMin ))
    {////借位
        datOutputDate->iHour -=1;
        datOutputDate->iMin  +=60;
    }
    if ( 0 > (datOutputDate->iHour) )
    {//借位
        datOutputDate->iDay -= 1;
        datOutputDate->iHour += 24;
    }
    /////
    if (0 >= (datOutputDate->iDay) )
    {//借位
        datOutputDate->iMonth -=1;
        if ( 0 >= (datOutputDate->iMonth) )
        {//借位
            datOutputDate->iYear -=1;
            datOutputDate->iMonth += 12;

        }
        /////
        if ( 0 == IsLeapYear(datOutputDate->iYear) )
        {//判斷不為閏年
            datOutputDate->iDay += NonLeapMonth[datOutputDate->iMonth-1];
        }
        else
        {//判斷為閏年
            datOutputDate->iDay += LeapMonth[datOutputDate->iMonth-1];
        } 
    }
    ////
}
////////////////////////////-------------------------
void CalWeekDiff(struct Date* datOutputDate,int iTotalDiffDay)
{
     int initWeek=3;

     int iDiffweek = iTotalDiffDay %7;

     if(  iDiffweek >= 0 )
     {
         datOutputDate->iWeek = (initWeek+iDiffweek) %7;
     }
     else
     {
         datOutputDate->iWeek = (initWeek+iDiffweek) %7;
         if ( datOutputDate->iWeek < 0 )
         {
             datOutputDate->iWeek += 7;
         }

     }

}
///////////////////////////--------------------------

struct Date CalDate(long lInputTime)
{
    //int temp =0;
    int iDiffsecond = 0;
    int iDiffMin    = 0;
    int iDiffHour   = 0;
    int iDiffday    = 0;
    int iDiffMonth  = 0;
    int iDiffYear   = 0;
    long lRemainSecond;

   
    int iTotalDiffDay = 0;
    
    struct Date datOutputDate ;
    InitDate(&datOutputDate);//初始化 [1970-01-01 00:00:00]

    if ( lInputTime >= 0 )
    {//判斷輸入的數值為正
        iDiffsecond = lInputTime % 60;
        iDiffMin    = (lInputTime /60 )%60;
        iDiffHour   = (lInputTime / 3600) %24;
        iDiffday    = (lInputTime / 86400);
        //
        iTotalDiffDay += iDiffday;
        //
        datOutputDate.iYear   = CalYear(&iDiffday);
        datOutputDate.iMonth  = CalMonth(&iDiffday,datOutputDate.iYear);
        CalDateDiff(&datOutputDate,iDiffday,iDiffHour,iDiffMin,iDiffsecond);   

        CalWeekDiff(&datOutputDate,iTotalDiffDay);        
    }
    else
    {//判斷輸入的數值為負

        iTotalDiffDay = -1;
        
        do 
        {
            if ( lInputTime < LONG_MUL_MIN)
            {//判斷超過可做乘法運算(*-1)的範圍 
                lRemainSecond = lInputTime - LONG_MUL_MIN;
                lInputTime = LONG_MUL_MIN;                
            }
            else
            {
                lRemainSecond = 0;
            }            
            
            lInputTime *= -1;
            iDiffsecond = lInputTime % 60;
            iDiffMin    = (lInputTime /60 )%60;
            iDiffHour   = (lInputTime % 86400) / 3600;
            iDiffday    = (lInputTime / 86400);
            //
            iTotalDiffDay -= iDiffday;
            //
            iDiffYear   = CalRevDiffYear(&iDiffday);
            iDiffMonth  = CalRevDiffMonth( &iDiffday,(datOutputDate.iYear-iDiffYear-1) );
                  
            CalRevDateDiff(&datOutputDate,iDiffYear,iDiffMonth,iDiffday,
                                          iDiffHour,iDiffMin,iDiffsecond);

            lInputTime = lRemainSecond;//繼續計算剩餘的秒數            

        }while ( lRemainSecond < 0 );
        CalWeekDiff(&datOutputDate,iTotalDiffDay);
        
    }
    return datOutputDate;
}
///////////////////////////////////
//主程式
///////////////////////////////////
int main(int argc,char* argv[] )
{
    
    long        lInputTime;
    struct Date datOutputDate;
    int         iTestInputValue;
    ///  
    #if DEBUG
    time_t        tNowTime;
    struct tm*    ptmUTCTime;

    ////抓取現在時間
    time ( &tNowTime );
    ////轉為tm的時間格式
    ptmUTCTime = gmtime(&tNowTime);
    #endif 


    if (2 != argc)
    {//未輸入參數
         printf("Please Input TimeValue ! \n");
        return 1;
    }
    //將輸入的參數轉為 整數
    //iTestInputValue = sscanf_s(argv[1],"%ld",&lInputTime);
    iTestInputValue = sscanf(argv[1],"%ld",&lInputTime);
    if ( (EOF ==iTestInputValue) || (0 ==iTestInputValue) )
    {//輸入參數錯誤
        printf("輸入參數錯誤\n");
        return 1;
    }
    //計算時間的對應日期
    datOutputDate = CalDate(lInputTime);
    //印出時間格式 [yyyy-mm-dd hh:mm:ss]
    PrintDate(datOutputDate);

    //////////////////

    #if DEBUG
    datOutputDate = CalDate((long)tNowTime);

    PrintDate(datOutputDate);

    printf ( "The current time is: %s", asctime(ptmUTCTime) );
    #endif 
    return 0;
}

undefined<



undefined
undefined
<
arrow
arrow
    全站熱搜

    rangerll 發表在 痞客邦 留言(0) 人氣()