gmtime与mktime的重新编写

news/2024/7/4 13:00:36

这几日发现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;
}

 

转载于:https://www.cnblogs.com/Fujunnnn/p/9860049.html


http://www.niftyadmin.cn/n/4556976.html

相关文章

还有数学考几个题目啊 大学C语言期末考试是以什么形式考啊

写程序 写答案3.给定一功能 完成程序2.读程序 实现特定功能 给定一段代码 不过3可能有6~7个小题 ||| 不同学校不一样的我们学校是这样的&#xff1a;1.填空 计算题就三题 选择3 填空2 填空等都是课后习题里选的现题数学考试类型&#xff1a;1 选择 都会做的 只要你听过课 放心吧…

20181027

今天我又双叒叕打炸了&#xff0c;膜拜一下rk1 jarden巨佬滴博客 T1&#xff1a;【from new_dtoj 2503: HZ(666666) loves meat&#xff08;meat&#xff09;】 题目描述 HZ(666666)终于打开了密码箱&#xff0c;发现里面只是一堆风干的肉条&#xff0c;于是他打算喂狗。 HZ(66…

编程高手进

首先你要弄明白的是&#xff1a;C语言是怎么工作的也就是说你写一段C语言代码会有什么样的效果&#xff08;等价于你说一名汉语是什么意思&#xff09; ||| 学习网站的话要有网站基础 里面高手如云 ||| 呵呵 分给我吧 51自学网 很不错 真的 里面什么都有 可以让你从入门到精通 …

mybatis开启驼峰转换

如果数据库中字段使用下划线作为分隔&#xff0c;而实体类属性用的小驼峰的方式命名&#xff0c;可以在mybatis的配置文件中开启驼峰转换 <setting name"mapUnderscoreToCamelCase" value"true"/>

2.redis集群搭建

集群模式下开启服务端 start-redis.sh 集群模式下开启客户端redis-cli -c -h 192.168.116.101 -p 7000集群模式下关闭服务端stop-redis.sh主从模式master -- slavekey&#xff1a; 互为副本存储hash 相当于分桶机制1.在 /soft/redis 目录 下suroot 用户 下2.mkdir conf cd c…

学习JAVA语言过程中遇到了一些问题

没有安当然不可以用 答案补充 QQ多少 看我能不能帮你 ||| 文档里没有写东西 html等等 我试过了可以啊 ||| 把那个文件直接改了扩展名就可以了 不行我再帮你看看 比如 你写了东西 在试这把HELLO该成小写 ||| 你在试试改成别的后缀名看会不会发生变化的 0KB 你什么都没有写 怎么编…

transition-

transition-timing-function&#xff1a;指定过渡速度曲线 ease&#xff08;默认&#xff09;&#xff1a;启动时为缓慢的转换效果&#xff0c;然后快速&#xff0c;缓慢结束 linear&#xff1a;从开始到结束具有相同速度的过渡效果 ease-in&#xff1a;慢速启动的过渡效果 eas…