2

「2011061411322100」という形式の文字列時刻を GMT に変換する必要があります。最初の試みは以下のとおりです。ただし、問題は、時間が別の PC から来ており、歴史的な時間であることです。そのため、リアルタイムで時間を取得していないため、コードが実行されているボックスの現地時間から単純に GMT を取得することはできません。

問題は、時間の変更中にコードが実行されている場合、時間の変更は私のボックスでは発生しますが、時間を取得しているリモートのボックスでは発生しないことです。ただし、ボックスにクエリを実行して、いつでも現在の時刻を取得できます。

したがって、詳細を説明するには:

  1. リモートボックスでジョブを開始します
  2. ジョブが完了します
  3. 実行中のジョブに関連する時間がいくつかあります
  4. 時刻を GMT に変換します

1. と 2. の間に時差(サマータイム)が発生すると、私はうんざりします。GMT 変換が壊れます。2) 現在のリモート ボックスの時間を取得し、58 分以上の差があるかどうかを確認し、それを変換に適用する必要があると思います。しかし、これを行うための信頼できる方法がわかりません。


string GMTConverter::strToGMT(const string& timeToConvert)
{
    // Set time zone from TZ environment variable. 
    _tzset();

    struct tm tmTime;


    //2011 06 14 11 32 21 00
     // (strToInt is just a wrapper for atoi) 
    int year = strToint(timeToConvert.substr(0, 4) );
    int month = strToint(timeToConvert.substr(4, 2) );
    int day = strToint(timeToConvert.substr(6, 2) );
    int hour = strToint(timeToConvert.substr(8, 2) );
    int min = strToint(timeToConvert.substr(10, 2) );
    int sec = strToint(timeToConvert.substr(12, 2) );

    cout<<"Time after parsing: "<<year<<"/"<<month<<"/"<<day<<" "<<hour<<":"<<min<<":"<<sec<<endl;

    // add to tm struct and return
    tmTime.tm_hour = hour; 
    tmTime.tm_min = min; 
    tmTime.tm_sec = sec; 
    tmTime.tm_mday = day; 
    tmTime.tm_mon = (month-1); 
    tmTime.tm_year = (year - 1900); 

    cout <<"Time in TM: "<<tmTime.tm_year<<"/"<<tmTime.tm_mon<<"/"<<tmTime.tm_mday<<" "<<tmTime.tm_hour<<":"<<tmTime.tm_min<<":"<<tmTime.tm_sec<<endl;

    char currDateTime[64];

     // For logging
    strftime(currDateTime, 63, "%c", &tmTime);
    cout <<"Actual time:"<<currDateTime<<endl;

    time_t remotePCTime = mktime( &tmTime );

    struct tm *gmt = gmtime( &remotePCTime );
    cout << "gmt = " << asctime( gmt ) << endl;

    char datebuf_2[12];
    char timebuf_2[13];
    strftime( datebuf_2, 13, "%Y-%m-%d\0", gmt );
    strftime( timebuf_2, 13, "%H:%M:%S\0", gmt );

    return string(datebuf_2) + "T" + string(timebuf_2) + "." + string("000");
}
4

3 に答える 3

2

明らかに信頼できる解決策は、送信するタイムスタンプに UTC (夏時間のない) を使用することです。固有のあいまいさを持つ時間システム (毎年 1 時間の重複があり、別の時間に同じタイム スタンプを取得できる) を使用すると、情報が失われるため、確実な方法を使用できなくなります。

リモート マシンが送信している時間形式を制御できない場合は、手元にある情報から推測することしかできません。たとえば、終了時間が開始時間よりも短い場合は、1 時間を追加します。ジョブに 1 時間以上かかった場合、これもあいまいさをもたらしますが、少なくとも時間が逆戻りすることはありません。

于 2011-06-27T12:16:39.427 に答える
1

時間の変更は年に 2 回表示されます。なぜ気にする必要があるのでしょうか。とにかく、時刻の形式を変更して時刻変更イベントを含めることはできませんか? または、時間の変更が表示される特定の日時と比較して、時間の変更中にジョブが完了したかどうかを確認しますか?

于 2011-06-27T12:04:41.237 に答える
1

リモート ジョブの開始時と終了時に現地時間を UTC で取得します。リモート ジョブの時刻を取得し、ジョブの開始時と終了時に UTC に変換します。元の投稿に記載されているように、コレクションの「歴史的な」時刻を GMT/UTC に変換します。このデータを構造体またはクラスにまとめて保持し、追加の開始終了時刻に LocalDLSValidation などの明確な名前を付けます。次のシナリオを確認する必要があります。

  1. Start and end time delta between Local and Remote is within allowed threshold(50mins?)

こちらはゴールドケース。歴史的な時間のコレクションを変更する必要はありません

 2. Local start/end time and remote time delta is outside threshold. 

これは 2 番目に単純なケースです。これは、時間のコレクション全体に + または - 時間をかけることができることを意味します。

 3.Local start time and remote time delta is within threshold.  But end is outside. 

これは、仕事の途中で変更が発生したことを意味するため、最悪のシナリオです。ジョブが 1 時間未満の場合、コレクション内のどの時間を + または - 1 時間にする必要があるかを簡単に確認できます。

1 時間を超える場合は....うーん。ここで問題が発生します。

   4.  Start time between local and remote is different but end time is different

OPのユースケースによれば、これは発生しないはずです。

于 2011-06-28T00:03:14.017 に答える