如何在C中添加分钟数

问题描述 投票:1回答:4

我具有使用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函数的正确方法是什么。

c
4个回答
0
投票

许多问题

错误时期

.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()


1
投票

不要重新发明轮子并接受必须解析的字符串。取而代之的是指向struct tm的指针。这样,“其他人”可以处理字符串输入。

struct tm *addMinutes(const struct tm *time, int nMin)
{
    time_t equivalent = mktime(time);
    equivalent += (nMin*60);

    return localtime(&equivalent);
}

0
投票

根据tp,tm_min参数仅采用0到59之间的整数。考虑在调用mktime(&t);之前使用一些if / while语句处理您的输入以确保小时和分钟被正确存储


0
投票

阅读所有回复后,我将代码更新为以下内容。

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));  
}
© www.soinside.com 2019 - 2024. All rights reserved.