用c计算到圣诞节的时间

Calculating the time until christmas day in c

我正在尝试用 c 语言编写一个程序,告诉您离圣诞节还有多少天。我以前从未使用过 time.h 库,所以我大部分时间都在使用它。我可以很容易地获得当前时间,但我的问题是我不确定如何正确输入圣诞节的信息,这会弄乱 差异时间计算。下面的代码在每次 运行 时输出不同的数字,但无论我尝试什么,我都无法正常工作。

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

int main()
{
time_t currentDate;
time (&currentDate);

struct tm * now;
now = localtime (&currentDate);

struct tm xmas;
xmas = *localtime(&currentDate);
xmas.tm_yday = 359;

double seconds = difftime(asctime(&xmas),asctime(&now));

double days=seconds/86400;

printf("%g days\n", days);


return 0;
}

您走在正确的轨道上,但 difftime 将 time_t 类型的变量作为参数。因此,不需要您使用的 'now' 变量。您拥有的 'xmas' 变量的初始化方式应该与您初始化它的方式略有不同。然后您可以在其上使用 mktime() 将其转换为类型 time_t 以便在 difftime().

中使用

请注意,在此编码沙盒中,您可以在浏览器中免费run/modify以下代码:https://www.next.tech/projects/4d440a51b6c4/share?ref=1290eccd

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

int main()
{
    double seconds, days;
    time_t currentDate;
    struct tm *xmas, today;

    time (&currentDate);

    today = *localtime(&currentDate);

    xmas = localtime(&currentDate);
    xmas->tm_mon = 11; // 0 == January, 11 == December
    xmas->tm_mday = 25;
    if (today.tm_mday > 25 && today.tm_mon == 11)
        xmas->tm_year = today.tm_year + 1;

    seconds = difftime(mktime(xmas),currentDate);
    days = seconds/86400;

    printf("%g days\n", days);

    return 0;
}

参考 - http://www.cplusplus.com/reference/ctime/difftime/

首先,你应该阅读libc手册中关于日期和时间的章节:

https://www.gnu.org/software/libc/manual/html_node/Date-and-Time.html

C 中的日期和时间处理有点糟糕,因此您需要很好地理解这些概念,以免混淆。

主要任务是调用difftime,目标时间为圣诞节,开始时间为当前时间。由于 difftime 以 time_t 格式接收时间,因此我们需要 time_t 格式的当前时间和圣诞节。对于 time_t 格式的当前时间,您可以使用 time() 函数。要将结构化日历时间转换为 time_t,您需要 mktime()。所以代码结束如下:

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

    int main(void)
    {
            time_t now;
            time_t christmas;
            struct tm tmp;
            double seconds;
            double days;

            time(&now);

            tmp.tm_sec = 0;
            tmp.tm_min = 0;
            tmp.tm_hour = 0;
            tmp.tm_mday = 25;
            tmp.tm_mon = 11; /* December == 11 */
            tmp.tm_year = 116; /* 2016 */
            tmp.tm_isdst = -1;

            christmas = mktime(&tmp);

            seconds = difftime(christmas, now);
            days = seconds/86400;

            printf("%g days untils christmas.\n", days);

            return 0;
    }

一些 MCU 根本没有浮点单元或只有 32 位 float,使用 double 要么一开始就不可能,要么成本很高。

这是一个纯整数版本,用于计算以天为单位的日期差异。

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

// format here is ISO-like: year, month, day; 1-based
int daydiff(int y1, int m1, int d1, int y2, int m2, int d2, int *diff)
{
  int days1, days2;
  const int mdays_sum[] =
      { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };

  // no checks for the other bounds here, feel free to add them
  if (y1 < 1708 || y2 < 1708) {
    *diff = INT_MAX;
    return 0;
  }
  // we add the leap years later, so for now
  //   356 days 
  // + the days in the current month
  // + the days from the month(s) before
  days1 = y1 * 365 + d1 + mdays_sum[m1 - 1];
  // add the days from the leap years skipped above
  // (no leap year computation needed until it is March already)
  // TODO: if inline functions are supported, make one out of this mess
  days1 += (m1 <= 2) ?
      (y1 - 1) % 3 - (y1 - 1) / 100 + (y1 - 1) / 400 :
      y1 % 3 - y1 / 100 + y1 / 400;

  // ditto for the second date
  days2 = y2 * 365 + d2 + mdays_sum[m2 - 1];
  days2 += (m2 <= 2) ?
      (y2 - 1) % 3 - (y2 - 1) / 100 + (y2 - 1) / 400 :
      y2 % 3 - y2 / 100 + y2 / 400;

  // Keep the signed result. If the first date is later than the
  // second the result is negative. Might be useful.
  *diff = days2 - days1;
  return 1;
}

问题"How many days until Christmas?"的实际答案给出

#include <time.h>
// Or Boxing-Day for our British friends
int days_until_next_xmas()
{
  int diff;
  time_t now;
  struct tm *today;

  // get seconds since epoch and store it in
  // the time_t struct now
  time(&now);
  // apply timezone
  today = localtime(&now);

  // compute difference in days to the 25th of December
  daydiff(today->tm_year + 1900, today->tm_mon + 1, today->tm_mday,
          today->tm_year + 1900, 12, 25, &diff);

  // Too late, you have to wait until next year, sorry
  if (diff < 0) {
    // Just run again.
    // Alternatively compute leap year and add 365/366 days.
    // I think that running it again is definitely simpler.
    daydiff(today->tm_year + 1900, today->tm_mon + 1, today->tm_mday,
            today->tm_year + 1900 + 1, 12, 25, &diff);
  }
  return diff;
}
int main()
{
  // days_until_next_xmas() returns INT_MAX in case of error
  // you might want to check
  printf("Next X-mas in %d days\n", days_until_next_xmas());
  exit(EXIT_SUCCESS);
}

上面的代码没有太多边界检查。请添加它们,特别是如果 int 数据类型少于 32 位(虽然现在大多数 MCU 都是 32 位的,但您可能不需要它并且只是为了单个日期计算而更改架构?)。如果是这种情况,请跳过将 1900 添加到 tm->tm_year 并更改对 1708 的检查。这将适用于 16 位 MCU。承认,对于 8 位 MCU, 会变得有点复杂。

int days_before_christ_mass()
{
    int months_day_size[] = {31,28,31,30,31,30,31,31,30,31,30,31};

int christ_mass_day = 25;
int months = 12;
int day = 26;

cout << "Month: " << months << endl;
cout << "Day: " << day << endl;
int zero_starter_month = months - 1;
if (zero_starter_month < 11) {
    if (day <= months_day_size[zero_starter_month]) {
        int daysSummation = abs(day - months_day_size[zero_starter_month]);
        //cout << daysSummation << endl;
        for (int i = zero_starter_month + 1; i < 11; i++)
            daysSummation += months_day_size[i];

        daysSummation = daysSummation + christ_mass_day;
        //cout << daysSummation << endl;;
        return daysSummation;
    }
    else {
        cout << "No such day" << endl;
        return -1;
    }
}
else if (zero_starter_month == 11) {

    if (day <= months_day_size[zero_starter_month]) {
        if (day <= christ_mass_day) {
            return christ_mass_day - day;
        }
        else {
            int day_summation = abs(day - months_day_size[zero_starter_month]);
            for (int i = 0; i < 11; i++)
                day_summation += months_day_size[i];
            day_summation += christ_mass_day;
            return day_summation;
        }
    }
    else {
        cout << "No such day" << endl
        return -1;
    }
}
else {
    cout << "There is no such month" << endl;
    return -1;
}
}

此代码适用于正 int 日和月输入,因为月和日永远不能为零和负数。