1

これを実現できるアルゴリズムを探してみましたが、結果は出ていません。

コンストラクタ Date2013(int dd) があります。

このメンバー関数では、月 (1 月、2 月など) を含む配列を作成しました。

次に、dd を取り、dd が 1 日から 31 日の間にある場合は 1 月を出力し、32 日から 59 日の間にある場合は 2 月を出力する if ステートメントを作成しました。

私が問題を抱えているのは、彼らが入力した数字 dd を取り、それを月の適切な日に変換することです。つまり、1 年の 34 日は 2 月 2 日です。

誰かがアルゴリズムを知っているか、これを達成する方法を知っていますか?

(私はC++を学び始めたばかりなので、コードの説明やコメントは本当に役に立ち、あなたの思考プロセスと構文を理解することができます)

4

2 に答える 2

6

最も移植性が高く信頼性の高い方法は、C または C++ で動作する ANSI C mktime および localtime 関数を使用することです。

アップデート:

標準 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;
};

仕事をするかもしれないサンプルコードを示すために、私が反対票を投じられないことを願っています. もちろん、必要に応じて自由に実装してください。これはアプローチの一例にすぎません。


プログラミングしているプラ​​ットフォームの標準Cライブラリに存在する可能性が最も高い既存のmktime機能(推奨)を使用したい場合は、私の元の回答内容が続きます...

mktime を使用する場合は、tm_mon=0 と tm_mday を必ずその年の日付に設定する必要があります (より詳しい説明については、mktime のドキュメントを参照してください)。 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 に答える