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
如果您有任何问题,请告诉我。
我有一些任务需要编写一个 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
如果您有任何问题,请告诉我。