22

C++ を学ぼうとして、Date クラスを作成しようとしています。

日が1から始まり、月が1から始まる日付に日を加算または減算するアルゴリズムを見つけようとしています.非常に複雑であることが証明されており、Googleはあまり現れません.

これを行うアルゴリズムを知っている人はいますか?

4

10 に答える 10

21

最も簡単な方法は、実際に 2 つの関数を作成することです。1 つは日を特定の開始日からの日数に変換し、もう 1 つは日付に変換します。日付が日数として表現されると、それに足したり引いたりするのは簡単です。

ここでアルゴリズムを見つけることができます: http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html

于 2010-02-26T19:47:41.733 に答える
16

アルゴリズム自体は実際には必要ありません(少なくとも名前に値するものではありません)。標準ライブラリは、手間のかかる作業のほとんどを実行できます。カレンダーの計算は非常に注意が必要です。1900年より前の日付が必要ない限り、次のようになります。

#include <ctime>

// Adjust date by a number of days +/-
void DatePlusDays( struct tm* date, int days )
{
    const time_t ONE_DAY = 24 * 60 * 60 ;

    // Seconds since start of epoch
    time_t date_seconds = mktime( date ) + (days * ONE_DAY) ;

    // Update caller's date
    // Use localtime because mktime converts to UTC so may change date
    *date = *localtime( &date_seconds ) ; ;
}

使用例:

#include <iostream>

int main()
{
    struct tm date = { 0, 0, 12 } ;  // nominal time midday (arbitrary).
    int year = 2010 ;
    int month = 2 ;  // February
    int day = 26 ;   // 26th

    // Set up the date structure
    date.tm_year = year - 1900 ;
    date.tm_mon = month - 1 ;  // note: zero indexed
    date.tm_mday = day ;       // note: not zero indexed

    // Date, less 100 days
    DatePlusDays( &date, -100 ) ; 

    // Show time/date using default formatting
    std::cout << asctime( &date ) << std::endl ;
}
于 2010-02-26T21:06:31.030 に答える
3

これはある種の演習用であると想定しています。それ以外の場合は、既に提供されている時間クラスを使用します。

特定の日付からのミリ秒数として時間を保存できます。次に、適切な値を追加し、クラスのアクセサーを呼び出すときに、それを日付に変換できます。

于 2010-02-26T19:46:20.177 に答える
2

これは非常に単純なアプローチのスケッチです。dアイデアを簡単にするために、追加する日数である が正であると仮定します。d以下をが負の場合に拡張するのは簡単です。

d365 未満か、365 以上dです。

dが 365 未満の場合:

m = 1;
while(d > numberOfDaysInMonth(m, y)) {
    d -= numberOfDaysInMonth(m, y);
    m++;
}
return date with year = y, month = m, day = d;

dが 365 より大きい場合:

while(d >= 365) {
    d -= 365;
    if(isLeapYear(y)) {
        d -= 1;
    }
    y++;
}
// now use the case where d is less than 365

または、たとえばユリウス形式で日付を表現し、ユリウス形式に追加して ymd 形式に変換することもできます。

于 2010-02-26T19:50:00.160 に答える
1

1 つのアプローチは、日付を日付のユリウス数にマップし、整数演算を行ってから元に戻すことです。

ジュリアン関数のリソースはたくさんあります。

于 2010-02-26T19:46:58.527 に答える
1

この機能を試してみてください。加算または減算を正しく計算します。dateTime 引数は UTC 形式である必要があります。

tm* dateTimeAdd(const tm* const dateTime, const int& days, const int& hours, const int& mins, const int& secs) {
    tm* newTime = new tm;
    memcpy(newTime, dateTime, sizeof(tm));

    newTime->tm_mday += days;
    newTime->tm_hour += hours;
    newTime->tm_min += mins;
    newTime->tm_sec += secs;        

    time_t nt_seconds = mktime(newTime) - timezone;
    delete newTime;

    return gmtime(&nt_seconds);
}

そして、使用例があります:

time_t t = time(NULL);
tm* utc = gmtime(&t);
tm* newUtc = dateTimeAdd(utc, -5, 0, 0, 0); //subtract 5 days
于 2013-10-06T13:40:40.370 に答える
0

最初に、年月日を固定日からの日数に変換するルーチンを作成することをお勧めします。たとえば、1.01.01 以降です。そして、それを元に戻す対称ルーチン。

うるう年を正しく処理することを忘れないでください。

この 2 つがあれば、あなたの仕事は簡単です。

于 2010-02-26T19:47:49.167 に答える