0

入力日を次の暦日に進めるために、次のコードを記述しました。これは、g++4.1.2でコンパイルされたダミーのソースファイルでテストした場合にうまく機能します。

ただし、私の会社のシミュレーター内から次のコードを実行すると(現時点では詳細はわかりません)、20021027で壊れます。つまり、20021027以外の日付の場合は意図したとおりに機能しますが、20021027の場合は20021027自体を返します。

何がうまくいかないのか教えてください。

int nextday(const int &date, int n=1)
{
    struct tm curr_time;

    int yyyy = curr_time.tm_year = date/10000-1900;
    int mm = curr_time.tm_mon=(date/100)%100-1;
    int dd = curr_time.tm_mday=date%100;
    curr_time.tm_min=0;
    curr_time.tm_sec=0;
    curr_time.tm_hour=0;

    time_t next = mktime(&curr_time) + 24*60*60*n;
    struct tm new_time;
    localtime_r(&next,&new_time);
    yyyy = 1900 + new_time.tm_year;
    mm = 1 + new_time.tm_mon;
    dd = new_time.tm_mday;
    return (10000*yyyy+100*mm+dd);
}
4

2 に答える 2

1

その1つの日付が問題を引き起こす理由はわかりませんが、なぜあなたが苦労しているのかはわかりません。tm_mdayを呼び出す前にフィールドに1つ追加し 、に渡したmktimeから修正された値を抽出するだけです。(ポインタが非定数を指すのには理由があります。)次のようなもの:struct tmmktimemktime

int
nextday( int date, int n = 1 )
{
    tm broken_down;
    broken_down.tm_year = date / 10000 - 1900;
    broken_down.tm_mon = (date / 100) % 100 - 1;
    broken_down.tm_mday = date % 100 + n;
    broken_down.tm_hour = 12;  // avoid issues with summer time, etc.
    broken_down.tm_min = 0;
    broken_down.tm_sec = 0;
    mktime( &broken_down );
    return (broken_down.tm_year + 1900) * 10000
        +  (broken_down.tm_mon + 1) * 100
        +  broken_down.tm_mday;
}

(いくつかの健全性チェックを追加することをお勧めします。つまり、int 渡された日付が実際に期待される形式の日付を表していること、およびそれ nが妥当な範囲内にあることを確認します。または、決定に影響を与えることができる場合は、標準の日付形式を使用します。する必要はありません。)

とにかく、特にローカルで同じ値で動作する場合は、シミュレーターに問題があるのではないかと思います。

于 2012-09-06T10:27:50.793 に答える
0

整数の制限である2147483647に達しただけで、切り捨てられます。

数値がその値を超える場合は、常にコードをチェックインしてください^^。unsignedに切り替えると、それが修正されるはずです(または、問題を4294967295に差し戻すだけです)。

編集:あなたは正しいです。私の答えは間違っています。

于 2012-09-06T09:49:56.170 に答える