C 中的日期比较

Date comparison in C

我有一些任务需要编写一个 C 程序来比较两个日期和returns中间有多少天。

问题是,变量标识符应该来自 time.h 库,所以我不能为这两个日期使用字符串或整数。 我知道 time.h 中的变量有 time_t 标识符,但我如何继续要求用户输入该类型的变量?我不知道我应该为这种类型在 printf 或 scanf 中放入什么。另外,有什么方法可以检查用户输入是否有效?

为了比较这两者,我想我应该使用 time.h 中也包含的 difftime() 函数,但话又说回来,我不确定。我在某处读到它以秒为单位显示差异,不确定该来源是否合法,但我真的不需要那个。我需要几天,因为我正在处理日期。

网上关于这个的material不多,这就是我寻求帮助的原因。提前致谢!

类型time_t只是一个秒数。您想要将其转换为 struct tm* 调用 localtime(time_t*)char *ctime(time_t*) 会给你一个字符串表示。对于格式化的输入和输出,您必须自己与 struct tm 的各个成员一起工作。

我假设您只需要两个日期之间的天数(而不是时间)。如其中一条评论所述,为用户输入选择您想要的任何格式,然后对其进行解析。

要求输入日期的最简单格式之一是 yyyymmdd 形式的整数。

例如,如果我想找到从我今年的生日(2016 年 5 月 27 日)到独立日(7 月 4 日)的天数,我将输入程序 20160527 和 20160704。

作为整数,它们相对容易转换为月、日和年。

声明一个 struct tm 并为其中的每一个设置年月日:

// Lets say the above dates were read into integers indate1 and indate2,
// so indate1 = 20160527 and indate2 = 20160704

#include <time.h>

struct tm dt = {0};
dt.tm_year = (indate1/10000) - 1900;
dt.tm_mon  = (indate1/100)%100;
dt.tm_mday = (indate1%100);

// Now convert to time_t:
time_t dt1 = mktime(&dt);

// Now do the same for indate2:
dt.tm_year = (indate2/10000) - 1900;
dt.tm_mon  = (indate2/100)%100;
dt.tm_mday = (indate2%100);
time_t dt2 = mktime(&dt);

// Now take the difference between the two dates:
double seconds = difftime( dt2, dt1 );

// Now convert to number of days:
unsigned long days = ( seconds / (60*60*24) );
fprintf( stdout, "The number of days between those two dates is %ld\n", days);

除了基于整数输入手动打包 struct tm 之外,您还可以使用 strptime 直接处理 string 输入。 strptime会根据提供的format字符串,将第一个参数提供的字符串转换为struct tm

您可能会发现这更方便,具体取决于您处理的输入类型。一个简短的例子是:

#define _XOPEN_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main (int argc, char **argv) {

    char *dtstr1 = argc > 1 ? argv[1] : "20160527";
    char *dtstr2 = argc > 2 ? argv[2] : "20160704";
    struct tm dt = {0};
    time_t dt1 = 0, dt2 = 0;

    /* convert input strings to struct tm */
    strptime (dtstr2, "%Y%m%d", &dt);    
    dt2 = mktime (&dt);

    strptime (dtstr1, "%Y%m%d", &dt);    
    dt1 = mktime (&dt);

    /* get difference in calendar time */
    double seconds = difftime (dt2, dt1);

    /* convert to number of days */
    long days = (seconds/(60*60*24));

    if (seconds < 0) /* output difference with occurrence orientation */
        printf ("%s occurs %ld days after %s\n", dtstr1, -days, dtstr2);
    else if (seconds > 0)
        printf ("%s occurs %ld days before %s\n", dtstr1, days, dtstr2);
    else
        printf ("%s and %s are contemporaneous\n", dtstr1, dtstr2);

    return 0;
}

注意: 虽然不太可能,但您可以在 days 转换中检查溢出)

示例Use/Output

$ ./bin/time_diff_days
20160527 occurs 38 days before 20160704

$ ./bin/time_diff_days 20160101 20150101
20160101 occurs 365 days after 20150101

$ ./bin/time_diff_days 20150101 20150101
20150101 and 20150101 are contemporaneous

如果您有任何问题,请告诉我。