我是C的初学者。
答案 0 :(得分:15)
是的,标准库C Time Library
包含您想要的结构和功能。您可以使用struct tm
来存储日期,使用difftime
来获取差异。
答案 1 :(得分:4)
保存日期是否有任何数据类型?
不,虽然对于“现在加上或减去几十年”范围内的日期,您可以在相关日期的(例如)午夜使用包含日期时间的time_t
或struct tm
。或者,您可以查看一个名为“Julian day”的东西:计算并将其存储在您喜欢的任何整数类型中。
C也有库吗?
标准功能都与日期/时间相关,而不仅仅是日期:mktime
,localtime
,gmtime
。
如何计算两个日期之间的差异
一旦你在time_t
中获得它,你可以减去两个并除以86400.但请注意,因为在两个不同日期的“午夜当地时间”可能不是相隔24小时的完全倍数。夏令时的变化。
如果您需要一个超出time_t
范围的日历,那么您基本上可以独立完成。如果time_t
是64位,则超过宇宙的年龄,但如果time_t
是32位,则对历史没有好处。或者甚至是养老金计划。无论如何,历史应用程序对日历都有自己的要求(儒略历,与格里高利完全无关的日历)。
答案 2 :(得分:3)
日期是否有任何数据类型?
不,C
中的内置数据类型,您必须定义用户定义的数据类型。
如何计算两个日期之间的差异?
你可以试试这个:
struct dt
{
int dd;
int mm;
int yy;
};
typedef dt date;
在main()中,您需要为类型data
声明三个变量
在以下示例today
差异中,
例如,您希望区分当前日期(c_date
)和出生日期(dob
)
date dob,c_date,today;
if(c_date.dd>=dob.dd)
today.dd = c_date.dd-dob.dd;
else
{
c_date.dd+=30;
c_date.mm-=1;
today.dd = c_date.dd-dob.dd;
}
if(c_date.mm>=dob.mm)
today.mm = c_date.mm-dob.mm;
else
{
c_date.mm+=12;
c_date.yy-=1;
today.mm = c_date.dd-dob.mm;
}
today.yy = c_date.yy-dob.yy;
在today
中,您有两个日期之间的差异。
还有一种方法:double difftime (time_t end, time_t beginning);
阅读此答案:
1. How to compare two time stamp in format “Month Date hh:mm:ss"
2. How do you find the difference between two dates in hours, in C?
答案 3 :(得分:2)
您可以创建一个名为日期的struct
,其中包含以下字段
typedef struct
{
int day;
int month;
int year;
}date;
这只是你想要的蓝图,现在是date
的制造和对象并且相应地工作。
要找出差异,请编写一个函数,分别对两个结构的day
month
和year
进行区分。
答案 4 :(得分:2)
您必须定义日期结构:
typedef struct date {
int day;
int month;
int year;
} Date;
然后定义一个简单的date_compare()
方法:
int date_compare(Date *date1, Date *date2) {
if (date1->year != date2->year)
return (date1->year - date2->year);
if (date1->month != date2->month)
return (date1->month - date2->month);
return (date1->day - date2->day);
}
答案 5 :(得分:1)
日期和时间的标准C库选项非常差,并且存在警告和限制。如果可能,请使用提供GDate and numerous useful date and time functions的Gnome Lib等库。这包括g_date_days_between()
以获取两个日期之间的天数。
这个答案的其余部分将限制在标准C库中,但如果你不必限制自己达到标准,不要自己折磨。日期非常艰难。
日期是否有任何数据类型?
struct tm
即可投放。只需将小时,分钟和秒钟保留为0。
确保struct tm
的所有字段都已正确填充的最简单方法是使用strptime
。
struct tm date;
strptime( "2017-03-21", "%F", &date );
puts( asctime(&date) ); // Mon Mar 21 00:00:00 2017
但这并不是存储日期的好方法。事实证明,使用Julian Days更好(见下文)。
在C中,我们有时间处理,是否还有一个日期?
如果您指的是time_t
,那也是日期时间。它是自"the epoch"以来在UTCIX系统上1970-01-01 00:00:00 UTC的秒数,但不一定是其他秒。不幸的是,它的安全范围仅为1970年至2037年,但任何最新版本的操作系统都将大大扩展该范围。
如何计算两个日期之间的差异?
取决于你想要什么。如果您想要秒数,可以使用struct tm
将time_t
转换为mktime
,然后使用difftime
,但这仅限于1970-2037安全范围time_t
。
int main() {
struct tm date1, date2;
strptime( "2017-03-21", "%F", &date1 );
strptime( "2018-01-20", "%F", &date2 );
printf("%.0lf\n", difftime(mktime(&date1), mktime(&date2)));
}
如果您想要天数,请{d} convert the dates into Julian days,即自公元前4714年11月24日以来的天数,并减去天数。虽然这看起来很荒谬,但这个相对简单的公式利用了日历周期,只使用整数数学。
// The formulas for a and m can be distilled down to these tables.
int Julian_A[12] = { 1, 1, 0 };
int Julian_M[12] = { 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int julian_day( struct tm *date ) {
int a = Julian_A[date->tm_mon];
int m = Julian_M[date->tm_mon];
int y = date->tm_year + 1900 + 4800 - a;
return date->tm_mday + ((153*m + 2) / 5) + 365*y + y/4 - y/100 + y/400 - 32045;
}
int main() {
struct tm date1, date2;
strptime( "2017-03-21", "%F", &date1 );
strptime( "2018-01-20", "%F", &date2 );
// 305 days
printf("%d days\n", julian_day(&date2) - julian_day(&date1));
}
还有其他简单的公式可以在Julian日期和日历日期之间进行转换。
难以获得数年,数月和数日的差异,因为一个月中的天数因月份和年份而异,并且因为必须将其标准化。例如,你不会说2年,1个月,2天。你说的是1年,11个月,29天(或者28个月,取决于月份)。因此,尽可能在Julian Days中进行日期数学运算。
要了解所涉及的内容,PHP implements this as date_diff
。看看the amount of C code required。
答案 6 :(得分:0)
/* Version 3 (better)
Date Difference between the two dates in days
like VBA function DateDiff("d", date1, date2)
in case of Gregorian. Same basic principle you
can translate in lot of other languages. This
is complete C code with date validity control.
*/
#include<stdio.h>
void main(){
long d1,m1,y1,d2,m2,y2;
printf("Enter first date day, month, year\n");
scanf("%d%d%d",&d1,&m1,&y1);
printf("Enter second date day, month, year\n");
scanf("%d%d%d",&d2,&m2,&y2);
if((IsValid(d1,m1,y1)==0)||(IsValid(d2,m2,y2)==0)){
printf("Invalid date detected\n");
}else{
d1=DatDif(d1,m1,y1,d2,m2,y2);
printf("\n\n Date difference is %d days\n",d1);
}
}// end main
long DatDif(d1,m1,y1,d2,m2,y2)
{ long suma;
suma=rbdug(d2,m2,y2) - rbdug(d1,m1,y1);
if(y1 != y2){
if(y1 < y2){
suma+=Godn(y1,y2);
}else{
suma-=Godn(y2,y1);
}
}
return(suma);
}// end DatDif
long Godn(yy1,yy2)
{ long jj,bb;
bb=0;
for(jj=yy1;jj<yy2;jj++){
bb+=365;
if(((((jj%400)==0)||((jj%100)!=0))
&&((jj%4)==0))) bb+=1;
}
return(bb);
}// end Godn
//Day of the Year
long rbdug(d,m,y)
{ long a,r[13];
r[1] = 0; r[2] = 31; r[3] = 59;
r[4] = 90; r[5] = 120; r[6] = 151;
r[7] = 181; r[8] = 212; r[9] = 243;
r[10]= 273; r[11]= 304; r[12]= 334;
a=r[m]+d;
if(((((y%400)==0)||((y%100)!=0))
&&((y%4)==0))&&(m>2)) a+=1;
return(a);
}//end rbdug
//date validity
long IsValid(dd,mm,yy)
{ long v[13];
if((0 < mm) && (mm < 13)){
v[1] = 32; v[2] = 29; v[3] = 32;
v[4] = 31; v[5] = 32; v[6] = 31;
v[7] = 32; v[8] = 32; v[9] = 31;
v[10]= 32; v[11]= 31; v[12]= 32;
if(((((yy%400)==0)||((yy%100)!=0))
&&((yy%4)==0))) v[2]+=1;
if((0 < dd) && (dd < v[mm])){
return(1);
}else{
return(0);
}
}else{
return(0);
}
}//end IsValid
答案 7 :(得分:0)
/* Version 4 ( 100 % correct):
Proleptic Gregorian date difference in days.
Date Difference between the two dates in days
like VBA function DateDiff("d", date1, date2)
and better (without limitations of DateDiff)
in case of Gregorian. Same basic principle you
can translate in lot of other languages. This
is complete C code with date validity control.
*/
#include<stdio.h>
void main(){
long d1,m1,y1,d2,m2,y2;
printf("Enter first date day, month, year\n");
scanf("%d%d%d",&d1,&m1,&y1);
printf("Enter second date day, month, year\n");
scanf("%d%d%d",&d2,&m2,&y2);
if((IsValid(d1,m1,y1)==0)||(IsValid(d2,m2,y2)==0)){
printf("Invalid date detected\n");
}else{
d1=DatDif(d1,m1,y1,d2,m2,y2);
printf("\n\n Date difference is %d days\n",d1);
}
}// end main
long DatDif(d1,m1,y1,d2,m2,y2)
{ long suma;
suma=rbdug(d2,m2,y2) - rbdug(d1,m1,y1);
if(y1 != y2){
if(y1 < y2){
suma+=Godn(y1,y2);
}else{
suma-=Godn(y2,y1);
}
}
return(suma);
}// end DatDif
long Godn(yy1,yy2)
{ long jj,bb;
bb=0;
for(jj=yy1;jj<yy2;jj++){
bb+=365;
if(IsLeapG(jj)==1) bb+=1;
}
return(bb);
}// end Godn
//Day of the Year
long rbdug(d,m,y)
{ long a,r[13];
r[1] = 0; r[2] = 31; r[3] = 59; r[4] = 90;
r[5] = 120; r[6] = 151; r[7] = 181; r[8] = 212;
r[9] = 243; r[10]= 273; r[11]= 304; r[12]= 334;
a=r[m]+d;
if((IsLeapG(y)==1)&&(m>2)) a+=1;
return(a);
}//end rbdug
//date validity
long IsValid(dd,mm,yy)
{ long v[13];
if((0 < mm) && (mm < 13)){
v[1] = 32; v[2] = 29; v[3] = 32; v[4] = 31;
v[5] = 32; v[6] = 31; v[7] = 32; v[8] = 32;
v[9] = 31; v[10]= 32; v[11]= 31; v[12]= 32;
if ((mm==2)&&(IsLeapG(yy)==1)) v[2]=30;
if((0 < dd) && (dd < v[mm])){
return(1);
}else{
return(0);
}
}else{
return(0);
}
}//end IsValid
//is leap year in Gregorian
long IsLeapG(yr){
if(((((yr%400)==0)||((yr%100)!=0))&&((yr%4)==0))){
return(1);
}else{
return(0);
}
}//end IsLeapG