C中两个日期之间的差异

Ehs*_*san 10 c date

我是C的初学者.

  • 日期是否有任何数据类型?
  • 在C我们有时间工作,还有一个日期吗?
  • 如何计算两个日期之间的差异?

pre*_*uin 16

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


Sch*_*ern 5

用于日期和时间的标准 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.


Is there any datatype for dates?

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

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

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

puts( asctime(&date) );  // Mon Mar 21 00:00:00 2017
Run Code Online (Sandbox Code Playgroud)

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

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

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.

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 tm to time_t using mktime and then use difftime, but that's limited to the 1970-2037 safe range of 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)));
}
Run Code Online (Sandbox Code Playgroud)

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.

// 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));
}
Run Code Online (Sandbox Code Playgroud)

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.

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


Gri*_*han 3

\n

有没有日期数据类型?

\n
\n\n

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

\n\n
\n

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

\n
\n\n

你可以试试这个:

\n\n
struct dt\n{\n  int dd;\n  int mm;\n  int yy;\n};\ntypedef dt date;  \n
Run Code Online (Sandbox Code Playgroud)\n\n

在 main() 中,您需要为 type 声明三个变量data
\n 在下面的today差异示例中,
\n 例如您想要获取当前日期 ( c_date) 和出生日期 ( dob) 之间的差异

\n\n
  date dob,c_date,today;\n\n  if(c_date.dd>=dob.dd)\n    today.dd = c_date.dd-dob.dd;\n  else\n  {\n      c_date.dd+=30;\n      c_date.mm-=1;\n      today.dd = c_date.dd-dob.dd;\n   }\n   if(c_date.mm>=dob.mm)\n     today.mm = c_date.mm-dob.mm;\n   else\n   {\n      c_date.mm+=12;\n      c_date.yy-=1;\n      today.mm = c_date.dd-dob.mm;\n   }\n   today.yy = c_date.yy-dob.yy;\n
Run Code Online (Sandbox Code Playgroud)\n\n

两个日期之间today有差异。

\n\n

还有另一种方法:\n阅读此答案:\n1。如何比较 \xe2\x80\x9cMonth Date hh:mm:ss" 格式的两个时间戳\n2.在 C 中如何找到两个日期之间的小时数差异?double difftime (time_t end, time_t beginning);


\n