计算直到圣诞节的时间c

时间:2016-08-20 20:59:56

标签: c date time codeblocks countdown

我试图在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;
}

4 个答案:

答案 0 :(得分:3)

您处于正确的轨道上,但是difftime将time_t类型的变量作为参数。因此,现在&#39;你不需要使用变量。圣诞节&#39;你应该以与初始化方式略有不同的方式初始化变量。然后你可以使用mktime()将它转换为time_t类型,以便在difftime()中使用。

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

答案 1 :(得分:1)

首先,您应该阅读有关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;
    }

答案 2 :(得分:1)

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日和月的正输入,因为月和日永远不能为零和负。

答案 3 :(得分: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;
}

问题的实际答案“圣诞节前几天?”给出

#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变得更加复杂。