うるう年のバグを防ぐためのコーディングプラクティスを開発するには?[クローズド]
質問
マイクロソフトは、日付の計算におけるソフトウェア エラー (うるう年以上) について によって Windows Azure に大規模な障害が発生したことを発表しました。 を引き起こしたことを発表しました。
を回避するための単純な判断ミスだったのでしょうか?
DateTime.Now.AddYears(1)
を閏年で使うというのは、本当に単純な判断ミスだったのでしょうか?
どのようなコーディングプラクティスがこれを防ぐことができたのでしょうか?
EDIT
dcstrawさんが指摘されているように
DateTime.Now.AddYears(1)
をうるう年で実行すると、.NETでは実際に正しい日付が返されます。 つまり、これはフレームワークのバグではなく、明らかに日付計算のバグです。
どのように解決するのですか?
恥知らずのプラグ。
より良い日付と時刻のAPIを使う
組み込みの.NETの日付と時刻のライブラリは、適切に使用するのが恐ろしく難しいです。それらは
は
は必要なことをすべて実行できますが
表現する
は、型システムを通して自分自身を明確に表現することができます。
DateTime
は混乱
,
DateTimeOffset
は、タイムゾーンの情報を実際に保存していないにもかかわらず、保存しているように思わせるかもしれませんし、また
TimeZoneInfo
は、考慮すべきすべてのことについて考えることを強制するものではありません。
また、ローカルタイムと特定のタイムゾーンの時間との間の明確な区別をすることもできません。また、グレゴリオ暦以外の暦を使いたい場合は
Calendar
クラスをずっと使い続けなければなりません。
これらのことから、私が作っている 野田時間 - の移植版である代替の日付と時刻のライブラリーを作っています。 ヨーダ時間 エンジン"engine" の移植版ですが、新しい(そしてより無駄のない)APIが上に乗っています。
意識しないと見逃しがちな、考えたいポイントもあります。
- ローカルの日付/時刻を特定のタイム ゾーンのものにマッピングすることは、思っているほど簡単ではありません。特定のローカルの日付/時刻は、夏時間の移行により、1 回、2 回 (あいまいさ)、または 0 回 (スキップされる) 発生する可能性があります。
-
タイムゾーンは歴史的に変化しています。
TimeZoneInfo
は、正直なところ、一般的に明らかにすることを望んでいます。(それは、標準時の概念が時間とともに変化するタイムゾーンをサポートしませんし、恒久的な夏時間を導入することもしません)。 - zoneinfo データベースがあっても、タイム ゾーン ID は必ずしも安定しているとは限りません。(CLDR はこれに対処しています。いずれ野田時間でもサポートしたいと思っていることです)。
- 日付と時刻のテキスト表現は、順序だけでなく、日付のセパレーター、時刻のセパレーター、および主格の月名のような奇妙なものの点で、悪夢のようなものです。
- 1 日の始まりは常に真夜中とは限りません。たとえばブラジルでは、春のサマータイムの移行により、壁の時計が午後 11:59:59 から午前 1 時に移動します。
- 場合によっては (私が知っている限りでは)、タイム ゾーンによって丸 1 日がスキップされることがあります - 2011 年 12 月 30 日はサモアでは発生しませんでした! ほとんどの開発者はこの件を無視できると思いますが、しかし......。
- グレゴリオ暦以外の暦を使用する場合は、注意深く、それがどのように動作するかを本当に理解していることを確認してください。
具体的な開発手法としては
- 何を本当に表現しようとしているのかを考える。 Noda Timeの核となる利点は、開発者にデータを表現するために様々な異なるタイプの中から選択することを強いることだと期待しています。それを正しく理解することで、他のすべてがよりシンプルになるのです。
- 思いつく限りのすべてをユニットテストしてください。もちろん、それはあなたのシステムが何をするのかによりますが 特に は、異なるタイムゾーン、夏時間の移行で何が起こるか、そしてもちろんうるう年を考慮してください。
-
を明示的に呼び出すのではなく、現在の時刻を伝えるためのサービスである時計のようなインターフェイスを注入することをお勧めします。
DateTime.Now
またはDateTime.UtcNow
ユニットテストが容易になります。 - 複数の操作を"now"で行っている場合、その日時を取得する 一度だけ を繰り返し要求するのではなく、一度だけ取得し、それを覚えておいてください。
- すべてを UTC で行うことは、常に答えとなるわけではありません。 ローカル の日付/時刻とタイムゾーンを保存する必要があります。
関連
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み】「namespace x already contains a definition for x」エラーの修正方法は?VS2010にコンバートした後に発生しました。
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み] [Solved] アセンブリ System.Web.Extensions dll はどこにありますか?
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】統合マネージドパイプラインモードで適用されないASP.NETの設定が検出された
-
[解決済み】ソケットのアドレス(プロトコル/ネットワークアドレス/ポート)は、通常1つしか使用できない?
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】aspNetCore 2.2.0 - AspNetCoreModuleV2 エラー
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。