c语言mktime函数遇到的一些坑

之前在调mktime函数,当转换时间时遇到多次调用该函数时小时数会出错,本来赋值的是一个数值,但是调用该函数以后数值被更改(小时数加一),出错的函数调用可表示为:

struct tm stm;
time_t t;

sscanf(date,"%d/%d/%d %d:%d:%d", &stm.tm_year,&stm.tm_mon,&stm.tm_mday,
            &stm.tm_hour,&stm.tm_min,&stm.tm_sec);
stm.tm_year   -=  1900; 
stm.tm_mon    -=  1;
t = mktime(&stm); 

其中data为输入字符串,包含相对于的时间格式,多次调用该函数时stm.tm_hour会加一,试了很多,排除其余代码内存改写问题,看网上很多mktime输入参数都是用指针方式做了以下测试代码后不会出现问题:

struct tm stm;
time_t t;

 time(&t);
 stm = localtime(&t); 
 sscanf(date,"%d/%d/%d %d:%d:%d", &(stm->tm_year),&(stm->tm_mon),&(stm->tm_mday),
            &(stm->tm_hour),&(stm->tm_min),&(stm->tm_sec));
 stm->tm_year   -=  1900; 
 stm->tm_mon    -=  1;
 t = mktime(stm); 

初步怀疑mktime在函数内部对struct tm有内存申请操作,如果用户传入了已经申请好的内存会出错,当然这好像不怎么符合正常的编码习惯,做个记录吧

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`mktime` 函数是 C 标准库中的函数,其实现比较复杂,需要考虑多个因素,比如闰年、夏令时、时区等。以下是一个简化版的 `mktime` 函数实现,仅考虑了不跨越夏令时和非闰年的情况: ```c #include <time.h> #define SECS_PER_DAY 86400 #define SECS_PER_HOUR 3600 #define SECS_PER_MINUTE 60 time_t my_mktime(struct tm *timeptr) { int year, month, day, hour, minute, second; int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 获取年、月、日、时、分、秒 year = timeptr->tm_year + 1900; month = timeptr->tm_mon + 1; day = timeptr->tm_mday; hour = timeptr->tm_hour; minute = timeptr->tm_min; second = timeptr->tm_sec; // 计算天数 int days = (year - 1970) * 365; for (int i = 1970; i < year; i++) { if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) { days++; } } for (int i = 1; i < month; i++) { days += days_in_month[i - 1]; } if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) { days++; } days += day - 1; // 计算秒数 time_t seconds = days * SECS_PER_DAY + hour * SECS_PER_HOUR + minute * SECS_PER_MINUTE + second; return seconds; } ``` 以上代码中,我们使用了一个 `days_in_month` 数组来保存每个月的天数,然后根据年、月、日计算出总共的天数,再将其转换为秒数即可。需要注意的是,由于 `struct tm` 结构体中的年份是从 1900 年开始计算的,因此需要将其加上 1900。此外,由于计算过程中没有考虑夏令时、时区等因素,因此在实际使用时可能会存在一定的误差。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值