C语言 C中两个日期之间的差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13932909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:47:08  来源:igfitidea点击:

Difference between two dates in C

cdate

提问by Ehsan

I'm a beginner in C.

我是 C 的初学者。

  • Is there any datatype for dates?
  • In C we have for working with time, is there one for dates too?
  • How can I calculate difference between two dates?
  • 日期有任何数据类型吗?
  • 在 C 中,我们有时间处理,日期也有吗?
  • 如何计算两个日期之间的差异?

采纳答案by Grijesh Chauhan

Is there any datatype for dates?

日期有任何数据类型吗?

No, inbuilt datatype in C, you have to defined user-defined data type.

不,内置数据类型C,您必须定义用户定义的数据类型。

How can I calculate difference between two dates?

如何计算两个日期之间的差异?

You may try this:

你可以试试这个:

struct dt
{
  int dd;
  int mm;
  int yy;
};
typedef dt date;  

In main() you need to declare three variables for type data.
In following example todaydifference,
for example you wants to take difference between current date (c_date) and date of birth (dob)

在 main() 中,您需要为 type 声明三个变量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;

In todayyou have difference between two dates.

today你有两个日期之间的差异。

There is one more way: double difftime (time_t end, time_t beginning);
Read this answers:
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?

还有一种方法: 阅读此答案: 1.如何比较格式为“Month Date hh:mm:ss”的两个时间戳2.如何在 C 中以小时为单位找到两个日期之间的差异?double difftime (time_t end, time_t beginning);


回答by prehistoricpenguin

Yes,the standard library C Time Librarycontains structures and functions you want.You can use struct tmto store date and difftimeto get the difference.

是的,标准库C Time Library包含您想要的结构和函数。您可以使用它struct tm来存储日期并difftime获取差异。

回答by Steve Jessop

Is there any datatype for save dates?

是否有保存日期的数据类型?

No, although for dates in the range "now plus or minus a few decades" you could use time_tor struct tmcontaining the datetime at (for example) midnight on the relevant day. Alternatively you could look into a thing called the "Julian day": compute that and store it in whatever integer type you like.

不,尽管对于“现在加上或减去几十年”范围内的日期,您可以使用time_tstruct tm包含相关日期(例如)午夜的日期时间。或者,您可以研究一个称为“儒略日”的东西:计算它并将其存储在您喜欢的任何整数类型中。

Is there any library for C too?

是否也有 C 语言库?

The standard functions all relate to date/times rather than just dates: mktime, localtime, gmtime.

标准函数都与日期/时间相关,而不仅仅是日期:mktime, localtime, gmtime

How can I calculate different between two date

如何计算两个日期之间的差异

Once you have it in a time_tyou can subtract the two and divide by 86400. Watch out, though, since "midnight local time" on two different days might not be an exact multiple of 24 hours apart due to daylight savings changes.

一旦将其放入 a 中,time_t您就可以将两者相减并除以 86400。但是请注意,由于夏令时的变化,两个不同日期的“当地时间午夜”可能不是 24 小时的精确倍数。

If you need a calendar that extends beyond the range of time_ton your implementation then you're basically on your own. If time_tis 64 bits then that's more than the age of the universe, but if time_tis 32 bits it's no good for history. Or pension planning, even. Historical applications have their own demands on calendars anyway (Julian calendar, calendars completely unrelated to Gregorian).

如果您需要一个超出实施范围的日历,time_t那么您基本上是靠自己的。如果time_t是 64 位,那么这超过了宇宙的年龄,但如果time_t是 32 位,那对历史不利。甚至养老金计划。无论如何,历史应用程序对日历有自己的要求(儒略历,与公历完全无关的日历)。

回答by Schwern

The standard C library options for dates and times are pretty poor and loaded with caveats and limitations. If at all possible, use a library such as Gnome Lib which provides GDate and numerous useful date and time functions. This includes g_date_days_between()for getting the number of days between two dates.

日期和时间的标准 C 库选项非常糟糕,并且充满了警告和限制。如果可能,请使用诸如 Gnome Lib 之类的库,它提供GDate 和许多有用的日期和时间函数。这包括g_date_days_between()获取两个日期之间的天数。

The rest of this answer will restrict itself to the standard C library, but if you don't have to limit yourself to the standard, don't torture yourself. Dates are surprisingly hard.

这个答案的其余部分将自身限制在标准 C 库中,但如果您不必将自己限制在标准中,请不要折磨自己。日期出奇地难。



Is there any datatype for dates?

日期有任何数据类型吗?

struct tmwill serve. Just leave the hour, minutes, and seconds at 0.

struct tm将服务。只需将小时、分钟和秒设为 0。

Simplest way to ensure all the fields of struct tmare properly populated is to use strptime.

确保struct tm正确填充所有字段的最简单方法是使用strptime.

struct tm date;
strptime( "2017-03-21", "%F", &date );

puts( asctime(&date) );  // Mon Mar 21 00:00:00 2017

But that's not a great way to store dates. It turns out it's better to use Julian Days (see below).

但这不是存储日期的好方法。事实证明最好使用 Julian Days(见下文)。

In C we have for working with time, is there one for dates too?

在 C 中,我们有时间处理,日期也有吗?

If you're referring to time_t, that is also for date-times. It's the number of seconds since "the epoch"which is 1970-01-01 00:00:00 UTC on POSIX systems, but not necessarily others. Unfortunately its safe range is only 1970 to 2037, though any recent version of an operating system will have greatly expanded that range.

如果您指的是time_t,那也适用于日期时间。这是自“时代”以来秒数,即 POSIX 系统上的 1970-01-01 00:00:00 UTC,但不一定是其他系统。不幸的是,它的安全范围只有 1970 年到 2037 年,尽管任何最新版本的操作系统都会大大扩展该范围。

How can I calculate difference between two dates?

如何计算两个日期之间的差异?

Depends on what you want. If you want the number of seconds, you could convert the struct tmto time_tusing mktimeand then use difftime, but that's limited to the 1970-2037 safe range of time_t.

取决于你想要什么。如果您想要秒数,您可以将 转换struct tmtime_tusingmktime然后使用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)));
}

If you want the number of days, you'd convert the dates into Julian days, the number of days since November 24, 4714 BC, and subtract. While that might seem ridiculous, this relatively simple formula takes advantage of calendar cycles and only uses integer math.

如果您想要天数,您可以将日期转换为 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));
}

There are other simple formulas for converting between Julian Dates and calendar dates.

还有其他简单的公式可用于在儒略日期和日历日期之间进行转换。

Getting diffs in years, months, and days is difficult because of the number of days in a month varies by month and year, and because it has to be normalized. For example, you wouldn't say 2 years, -1 months, 2 days. You'd say 1 year, 11 months, 29 days (or maybe 28, depends on the month). For this reason, do date math in Julian Days whenever possible.

获得年、月和日的差异很困难,因为一个月中的天数因月份和年份而异,并且必须对其进行标准化。例如,您不会说 2 年、-1 个月、2 天。你会说 1 年、11 个月、29 天(或者可能是 28 天,取决于月份)。因此,请尽可能在 Julian Days 中进行日期数学运算。

To get an idea of what's involved, PHP implements this as date_diff. Have a look at the amount of C code required.

为了了解所涉及的内容,PHP 将其实现为date_diff. 查看所需的 C 代码量

回答by Omkant

You can create a structnamed datehaving following fields

您可以创建具有以下字段的struct命名日期

typedef struct 
{
 int day;
 int month;
 int year;
}date;

It's just a blueprint what you want , now make and object of dateand work accordingly. To find the difference ,write a function to take a difference between daymonthand yearof the both stucts respectively.

这只是您想要的蓝图,现在制作和对象date并相应地工作。要找到差异,编写一个函数来取之间的差异daymonth,并year分别在这两个stucts的。

回答by martynas

You have to define a date struct:

您必须定义一个日期结构:

typedef struct date {
    int day;
    int month;
    int year;
} Date;

And then define a simple date_compare()method:

然后定义一个简单的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);

}

回答by Eagle11

/*  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

回答by Darijo11

/* 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