論理的に (絶対的ではなく) 期間を現地時間に追加し、将来的に有効な現地時間を取得する方法はありますか?
たとえば、1 日目の午前 11 時に 1 日追加すると、その間に夏時間の変更 (+/- 1 時間) があったとしても、2 日目の午前 11 時になりますか? 時間が存在しない場合は、エラーまたは次の有効な時間が返される可能性があります。
C++ 標準メカニズム、Windows API 関数、STL および/または Boost クラスはすべて問題ありません。
のような現地時間で開始し、同時に次の暦日2013-07-02 18:30:00
に移動したい場合は、他の人の提案にもかかわらず、UTC を使用したくありません。
あなたは暦時間で働いています。UTC は瞬間的な時間を測定するためのものです。カレンダー時間は、DST の変更により不連続になる場合がありますが、瞬間時間はそうではありません。
瞬間時間に1 日を追加すると、常に正確に 24 時間が追加されます。ただし、カレンダーの時刻に 1 日追加すると、カレンダーが 1 日分進みます。それは微妙ですが、明らかに異なります。暦日には、実際に 23、24、または 25 時間かかる場合があります。
不連続性に関しては、クロックが 1 時間スキップする「スプリング フォワード」遷移に対処する必要があります。1 日追加してこのギャップに到達すると、カレンダーに存在しない時間を参照していることになります。この場合、何をしたいのかを決める必要があります。次の可能な時間に進むべきですか?それともエラーにするべきですか?または、この場合はさらに 1 時間追加することもできます。それはあなた次第です。
もう 1 つの不連続性は、クロックが 1 時間ロールバックする「フォールバック」遷移です。この単一のカレンダーの位置が参照できる実際の瞬間が2 つあるかもしれませんが、カレンダーの時間だけに関心があるので、それが直接影響することはありません。それがどのインスタントにマッピングされるかを知りたい場合は、おそらく何らかのビジネス ロジックを含むか、UI を介してユーザーに尋ねるなど、決定を下す必要があります。
不連続がどこにあるかを知るには、タイム ゾーン データベースが必要です。IANAデータベースは事実上の標準です。
C++ の場合、Boost の日付と時刻のサポートの使用を検討する必要があります。彼らは標準データベース (別名「ZoneInfo」) を使用しており、ここでその使用について説明しています。おそらくlocal_time
.
可能な限り、 のような POSIX タイム ゾーン設定PST8DST
には近づかないでください。Boost はそれらをサポートしていますが、それらは暗号化されており、一般的に国際的に使用するのは困難です。America/New_York
IANA タイム ゾーンには、やなどのエリアと場所で構成されるルックアップ キーがありますEurope/London
。
Boost のlocal_time::ambiguous_result
とも参照してくださいlocal_time::time_label_invalid
。それらは、あなたが不連続にあるかどうかを教えてくれます。
また、(IMHO)、ローカルの日時、タイムゾーン、DST などを操作することは、C++ では他のどの言語よりもはるかに複雑です。PHP、Python、.Net、Ruby などの優れたソリューションがあります。 Boost はおそらく C++ 向けの最も包括的な日付/時刻の実装を備えていますが、.Net の Noda Time のようなライブラリほど単純ではありません。
アップデート
Boost の IANA/Olson タイム ゾーンのサポートには欠陥があることに気付きました。彼らのタイム ゾーン データ ファイルは、IANA/Olson タイム ゾーン データベースの豊富な履歴を取り除きます。これは、タイム ゾーン タグ wiki で説明したPOSIX タイム ゾーンのすべての問題を本質的に再現します。したがって、タイム ゾーンの変換に Boost を使用することはお勧めしません。
代わりに、ICU、またはGNU C ライブラリのタイム ゾーン関数(ここで説明) を検討してください。どちらも IANA/Olson タイム ゾーン データ全体を使用します。
それは一種のセマンティクスに依存します。
現地時間が正確に半日になることに興味がある場合は、はい: UTC に変換し、半日を追加して、現地時間に戻します。
一方、主に現地時間で作業する場合 (たとえば、電力負荷予測でこれを行っています)、別の方法を取る可能性があります。現地時間を UTC であるかのようにし、半日を追加してから、それを現地時間として扱い、サニティ チェックを行うために UTC に戻します。いくつかの現地時間は存在しないことに注意する必要があります。曖昧。