1

我尝试寻找一种可以实现这一目标的算法,但没有得出任何结果。

我有构造函数 Date2013(int dd)。

在这个成员函数中,我创建了一个包含月份的数组(一月、二月等)

然后我创建了一个 if 语句,它接受 dd,如果 dd 在第 1 天 -31 天之间,则输出一月,如果它在 32 - 59 天之间,则输出二月。

我遇到的麻烦是,然后将他们输入的数字 dd 转换为当月的适当日期。即(一年中的第 34 天是 2 月 2 日)。

有谁知道任何算法或知道我可以实现这一目标的方法吗?

(我刚刚开始学习我的 C++,所以任何代码中的解释或注释都会非常有帮助,这样我就可以理解你的思维过程和语法)

4

2 回答 2

6

最便携和最可靠的方法是使用 ANSI C mktime 和 localtime 函数,它们可以与 C 或 C++ 一起使用

更新:

要回答有关如何实现自己的算法而不是使用标准 C 库 mktime 函数的问题,一个很好的起点是查看已知的工作代码,例如glibc mktime 源代码。您需要的相关花絮包括:

glibc 2.17 (HEAD) mktime.c第 141 行开始:

#define TM_YEAR_BASE 1900

/* Return 1 if YEAR + TM_YEAR_BASE is a leap year.  */
static inline int
leapyear (int year)
{
  /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
     Also, work even if YEAR is negative.  */
  return
    ((year & 3) == 0
     && (year % 100 != 0
         || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
}

glibc 2.17 (HEAD) mktime.c第 160 行开始:

const unsigned short int __mon_yday[2][13] =
{
    /* Normal years.  */
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    /* Leap years.  */
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};

实现将 year 和 dayOfYear 转换为相应的 month 和 dayOfMonth 的构造函数的示例 C++ 类可能类似于:

#include <iostream>
using namespace std;

#define MONTHS_IN_YEAR 12

class MyDateClass {
public:
MyDateClass(int year, int dayOfYear) {
    int yearOffset = dayOfYear - TM_YEAR_BASE;
    int leapYearIndex = leapyear(year) ? 1 : 0;
    int daysInYear = leapYearIndex ? 366 : 365;

    this->year = year;
    this->dayOfYear = dayOfYear;

    if (dayOfYear >= 1 && dayOfYear <= daysInYear) {
        for (int mon = 0; mon < MONTHS_IN_YEAR; mon++) {
           if (dayOfYear <= __mon_yday[leapYearIndex][mon+1]) {
               month = mon + 1;
               dayOfMonth = dayOfYear - __mon_yday[leapYearIndex][mon];
               break;
           }
        }
    } else {
        cerr << "day of year must be between 1 and " << daysInYear << endl;
        month = 0;
        dayOfMonth = 0;
    }
}

// Get month 1=January, 12=December       
inline int getMonth() { return month; }

// Get day of month
inline int getDayOfMonth() { return dayOfMonth; }

// Get year
inline int getYear() { return year; }

// Get day of yar
inline int getDayOfYear() { return dayOfYear; }

private:
   int month;
   int dayOfMonth;
   int year;
   int dayOfYear;
};

希望我不会因为展示可能完成这项工作的示例代码而被否决。当然,您可以随意实现它。这只是一种示例方法。


如果您更愿意使用现有的 mktime 功能(推荐),它很可能存在于您正在编程的任何平台上的标准 C 库中,我的原始答案内容如下...

使用 mktime 时,您需要确保将 tm_mon=0 和 tm_mday 设置为一年中的某一天(请参阅 mktime 文档以获得更好的解释),但简而言之,mktime 忽略 tm_wday 和 tm_yday 并且只翻译 tm_mday,它基本上解释为如果您还设置了 tm_mon = 0,则为一年中的某一天;

以下是一些说明这一点的工作示例代码,可以在 C 或 C++ 中工作:

#include <stdio.h>      /* printf, scanf */
#include <time.h>       /* time_t, struct tm, time, mktime */
#include <strings.h>    /* bzero */

int main () {
   time_t loctime;
   struct tm timeinfo, *loctimeinfo;
   int year, day;

   /* prompt user for year and day-of-the-year */
   printf ("Enter year: "); scanf ("%d",&year);
   printf ("Enter day of the year: "); scanf ("%d",&day);

   /* initialize timeinfo and modify it to the user's choice */
   bzero(&timeinfo, sizeof(struct tm));
   timeinfo.tm_isdst = -1;  /* Allow mktime to determine DST setting. */
   timeinfo.tm_mon   = 0;
   timeinfo.tm_mday = day;
   timeinfo.tm_year = year - 1900;

   loctime = mktime (&timeinfo);
   loctimeinfo = localtime(&loctime);

   printf ("The date for that day of the year is %s.\n", asctime(loctimeinfo));

   return 0;
}

编译和示例运行:

$ g++ -o t2 t2.c
$ ./t2
Enter year: 2013
Enter day of the year: 1
The date for that day of the year is Tue Jan  1 00:00:00 2013

$ ./t2
Enter year: 2013
Enter day of the year: 365
The date for that day of the year is Tue Dec 31 00:00:00 2013

甚至适用于像 2012 年这样的闰年:

$ ./t2
Enter year: 2012
Enter day of the year: 366
The date for that day of the year is Mon Dec 31 00:00:00 2012
于 2013-07-13T21:45:18.553 回答
2

所以,计算这个的基本原则是有一个“每月天数”的列表,基本上。

int days_in_month[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

如果我们有一个名为的变量days,它是一年中的天数,amonth表示我们在哪个月份结束:

从 "month = 1;" 开始,只需检查 是否days小于days_in_month[month],以及它是否不是days_in_month[month]从天数中减去,然后继续进行,直到您达到月 = 12 并且仍然有更多天数和天数超过days_in_month[month][which意味着它是明年,从 开始month=1,然后移动到下一个year- 但我认为你的任务仅限于 1-365 天,所以现在只报告错误就可以了]。

当天数不超过days_in_month[month]时,您拥有该月的天数。

请注意,我故意没有编写如何执行此操作的代码,而是描述了如何执行此操作。因为我是这种代码至少写过几次的人,而你是努力学习的人。您不是通过从 SO 中复制和粘贴来学习的。

编辑:是的,我完全忽略了闰年。2013 年不是闰年,所以我们不在乎... ;)

于 2013-07-13T23:10:39.727 回答