我具有使用struct tm和maketime在C中的日期时间添加任何分钟的功能。该函数以字符串形式输入日期时间,以整数形式分钟,然后将分钟数添加到日期时间,然后返回字符串。
char *addMinutes(char *dateTime, int mins)
{
/* Intput & Output: YYYYMMDDHHMM */
char year[5];
char month[3];
char day[3];
char HH[3];
char MM[3];
char newDateTime[13];
struct tm t;
STRMCPY(year, dateTime, 4);
STRMCPY(month, &dateTime[4], 2);
STRMCPY(day, &dateTime[6], 2);
STRMCPY(HH, &dateTime[8], 2);
STRMCPY(MM, &dateTime[10],2);
printf("input %s %s %s %s %s\n",year,month,day,HH,MM);
t.tm_year = atoi(year);
t.tm_mon = atoi(month)-1;
t.tm_mday = atoi(day);
t.tm_hour = atoi(HH);
t.tm_min = atoi(MM)+mins;
printf("input %d %d %d %d %d\n",t.tm_year,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min);
mktime(&t);
printf("input %d %d %d %d %d\n",t.tm_year,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min);
sprintf(newDateTime, "%04d%02d%02d%02d%02d", t.tm_year, t.tm_mon,
t.tm_mday,t.tm_hour,t.tm_min);
return newDateTime;
}
下面是我调用上面函数的结果strcpy(atb30,addMinutes(“ 201812120431”,30));
input 2018 12 12 04 31
input 2018 11 12 4 61
input 2018 11 12 5 41
atb 201811120541
我不明白为什么我的程序无法正常工作。用C编写addMinutes函数的正确方法是什么。
许多问题
错误时期
.tm_year
成员来自1900。@paddy
// t.tm_year = atoi(year);
t.tm_year = atoi(year) - 1900;
检查成功
// mktime(&t);
if (mktime(&t) == -1) {
puts("Failed conversion");
exit(EXIT_FAILURE);
}
未完成的作业
以下代码未分配t
的其他成员,从而导致可疑的结果。相反,如果您不知道日期的设置,请完全分配t
,并使用-1
作为.tm_isdst
。
// struct tm t;
struct tm t = { 0 };
t.tm_isdst = -1; // add
t.tm_year = atoi(year) - 1900;
t.tm_mon = atoi(month) - 1;
t.tm_mday = atoi(day);
t.tm_hour = atoi(HH);
t.tm_min = atoi(MM) + mins;
if (mktime(&t) == -1) {
puts("Failed conversion");
exit(EXIT_FAILURE);
}
返回无效指针
return newDateTime;
尝试返回一个指向本地数组的指针。这是未定义的行为。代码需要一种新方法。建议传递到函数分配中以存储新的newDateTime
。
小缓冲区大小
char newDateTime[13];
已经足够了。如果年份超过4个字符,会发生什么情况?
// char newDateTime[13];
// sprintf(newDateTime, "%04d%02d%02d%02d%02d",
// t.tm_year, t.tm_mon, t.tm_mday,t.tm_hour,t.tm_min);
char newDateTime[13 * 2];
snprintf(newDateTime, sizeof newDateTime, "%04d%02d%02d%02d%02d",
t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min);
也正在研究strftime()
。
不要重新发明轮子并接受必须解析的字符串。取而代之的是指向struct tm
的指针。这样,“其他人”可以处理字符串输入。
struct tm *addMinutes(const struct tm *time, int nMin)
{
time_t equivalent = mktime(time);
equivalent += (nMin*60);
return localtime(&equivalent);
}
根据tp,tm_min
参数仅采用0到59之间的整数。考虑在调用mktime(&t);
之前使用一些if / while语句处理您的输入以确保小时和分钟被正确存储
阅读所有回复后,我将代码更新为以下内容。
void addMinutes(char *dateTime, int mins,char *newDateTime)
{
/* Intput & Output: YYYYMMDDHHMM */
char year[5];
char month[3];
char day[3];
char HH[3];
char MM[3];
struct tm *info;
STRMCPY(year, dateTime, 4);
STRMCPY(month, &dateTime[4], 2);
STRMCPY(day, &dateTime[6], 2);
STRMCPY(HH, &dateTime[8], 2);
STRMCPY(MM, &dateTime[10],2);
struct tm t = { 0 };
t.tm_isdst = -1;
t.tm_year = atoi(year)-1900;
t.tm_mon = atoi(month)-1;
t.tm_mday = atoi(day);
t.tm_hour = atoi(HH);
t.tm_min = atoi(MM)+mins;
t.tm_sec = 0;
if (mktime(&t) == -1) {
printf("Failed conversion\n");
exit(-1);
}
time_t equivalent = mktime(&t);
strftime(newDateTime,80,"%Y%m%d%H%M", localtime(&equivalent));
}