gmtime与mktime的重新编写

这几日发现Linux的mktime与gmtime所处理的数据类型是32位的,即代表时间设置只能设置到2038年,在公司的产品要实现这个时间的突破还是得自己写一个新的处理时间的函数。

作为一个刚毕业的程序员,老板把这个任务交给我了,虽然到最后老板没有采纳我的算法,但是还是po上我的算法,作为我的第一篇文章吧。欢迎各位大神来指错我的错误,谢谢。

部分代码是从网上一位前辈那借鉴而来的,网址找不到了。

typedef unsigned long long time_t2;

const unsigned short int mon_yday[][13] =
{
    //正常年限: 
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    //闰年: 
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};

//判断一个年份是否为闰年,是就返回1,不是就返回0 
static int isLeapYear(int year)
{
    return((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}

//获取一年的天数 
static int getDaysForYear(int year)
{
    return (isLeapYear(year) ? 366 : 365);
}

#define START_YEAR        (1970ULL)
#define SECOND_DAY      (86400ULL)    //60*60*24
#define SECOND_HOUR     (3600ULL)    //60*60
#define SECOND_MIN      (60)    //60
#define SECOND_YEAR     (365*24*3600ULL)
time_t2 mktime2(struct tm *timeVal)
{
    time_t2 retVal = 0;

    retVal += (timeVal->tm_year - 70)* getDaysForYear((timeVal->tm_year) + 1900) * SECOND_DAY; // 年份 
    retVal += mon_yday[isLeapYear((timeVal->tm_year) + 1900)][timeVal->tm_mon] * SECOND_DAY; //月份 
    retVal += (timeVal->tm_mday + ((timeVal->tm_year - 70) / 4 - (timeVal->tm_year - 70) / 100 + (timeVal->tm_year - 70) / 400) - 1) * SECOND_DAY; //
    retVal += timeVal->tm_hour * SECOND_HOUR; //小时 
    retVal += timeVal->tm_min * SECOND_MIN; //分钟 
    retVal += timeVal->tm_sec; //

    return retVal;
}
//根据秒数计算日期 
static void getDate(time_t2 second, int *year, int * month, int* day, int *yday)
{
    int days = second / SECOND_DAY;
    time_t2 tempSecond;
    int curYear = START_YEAR, addYears = 0;
    int leftDays = days;
    int i = 1;

    //计算年份 
    int daysCurYear = getDaysForYear(curYear);
    while (leftDays >= daysCurYear)
    {
        leftDays -= daysCurYear;
        curYear++;
        addYears++;
        daysCurYear = getDaysForYear(curYear);
    }
    *year = addYears + 70;

    //计算月与日 
    tempSecond = second - addYears *SECOND_YEAR - ((addYears / 4 - addYears / 100 + addYears / 400) - 1)*SECOND_DAY;
    days = tempSecond / SECOND_DAY;        //除去年份后剩下的天数 
    *yday = days - 1;
    int IsLeapYear = isLeapYear(*year + 1900);
    for (i; i < 13; i++)
    {
        if (days <= mon_yday[IsLeapYear][i])
        {
            *month = i - 1; // mon是[0,11],所以-1
            *day = days - mon_yday[IsLeapYear][i - 1];
            break;
        }
    }

}
//计算时间 
static void getTime(time_t2 seconds, int* hour, int* minute, int* second)
{
    time_t2 leftSeconds = seconds % SECOND_DAY;
    *hour = leftSeconds / SECOND_HOUR;
    *minute = (leftSeconds % SECOND_HOUR) / SECOND_MIN;
    *second = leftSeconds % SECOND_MIN;
}
struct tm * gmtime2(time_t2 *secVal)
{
    static struct tm TimeVal;
    getDate(*secVal, &TimeVal.tm_year, &TimeVal.tm_mon, &TimeVal.tm_mday, &TimeVal.tm_yday);
    getTime(*secVal, &TimeVal.tm_hour, &TimeVal.tm_min, &TimeVal.tm_sec);
    TimeVal.tm_wday = GetWeekIndex(TimeVal.tm_year + 1900, TimeVal.tm_mon + 1, TimeVal.tm_mday);
    return &TimeVal;
}

猜你喜欢

转载自www.cnblogs.com/Fujunnnn/p/9860049.html