15

保険業界にいる私のクライアントは、被保険者候補の生年月日を要求しています。jQuery datepicker を使用して Web フォームに入力され、Knockout を使用してモデル プロパティに接続され、JSON の ajax 経由で MVC 4 コントローラーに送信されます。

一部の保険契約者は、誤った生年月日で保険書類を受け取りました。その後の調査中に、ごくわずかなデータ入力エラーに加えて、間違った日付が次の 2 つの期間に集中していることがわかりました。

  • 3月下旬から4月上旬までの3週間
  • 10月の最終週から11月の第1週まで。

私たちのクライアントはアメリカ/モントリオールのタイムゾーンにいるので、すぐに DST の問題を考えました。このタイムゾーンの DST 規則は 2007 年に変更されました

いくつかの記事やその他の Stack Overflow の質問を読んで、ECMAScript 5 標準では、実装では現在の DST ルールを考慮する必要があり、DST の変更履歴を尊重する必要はないと規定されていることがわかりました。ES5 15.9.1.8現時点でこの仕様に準拠していない唯一のブラウザーは IE10 です (これについては後で詳しく説明します)。

この仕様を考えると、ブラウザーは次のように日付を報告します (Chrome でテスト済み)。

(new Date(2006, 9, 31, 0, 0, 0)).toISOString()
// 2006-10-31T04:00:00.000Z

(new Date(2008, 9, 31, 0, 0, 0)).toISOString()
// 2008-10-31T04:00:00.000Z

.NET プラットフォームでは、次のように日付が正しく報告されます。

DateTime dt = new DateTime(2006, 10, 31, 0, 0, 0);
Console.WriteLine("{0:MM/dd/yy H:mm:ss zzz}", dt);
// 10-31-06 0:00:00 -05:00
dt = new DateTime(2008, 10, 31, 0, 0, 0);
Console.WriteLine("{0:MM/dd/yy H:mm:ss zzz}", dt);
// 10-31-08 0:00:00 -04:00

この問題の原因の 1 つは、被保険者が 2007 年より前の 10 月の最後の週に生まれた場合、UTC 時刻が MVC コントローラーに誤って報告されることです。次に例を示します。

Javascript 日付オブジェクト:

new DateTime(2006, 9, 31, 0, 0, 0);

.Net は JSON データを解析し、以下を取得します。

10-30-06 23:00:00 GMT

テスト中に、JavaScript の Date オブジェクトの内部表現が .Net DateTime の内部表現と互換性がないことがわかり、JavaScript 表現を使用して独自のパーサーをロールバックできませんでした。

Javascript :

(new Date(2006, 9, 31, 0, 0, 0)).getTime()
// 1162267200000

.ネット:

DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(1162267200000);
Console.WriteLine("{0}", dt);
// 2006-10-31 04:00:00

(現地時間で 2006 年 10 月 30 日 23:00 として表されているため、これは誤りです。)

私のクライアントのユース ケースでは、関心のある日付部分なので、Date オブジェクトの時刻部分を正午に設定するだけで、JavaScript 側での日付の誤解のすべてのケースから保護されます。残念ながら、これは醜いパッチであり、クライアントが過去に発生したイベントの正確な日時を要求する機能を実装することを望んでいる場合など、他の潜在的な状況を解決するものではありません。

もう 1 つの方法は、コントローラーで潜在的に問題のある DST の週を検出するアルゴリズムを作成し、問題の週の日付を取得した場合に正しい時刻を設定することです。残念ながら、ECMAScript 6 標準では、DST の変更履歴を尊重する必要があると指定されているため (したがって、将来のすべてのブラウザーはその状況を正しく処理する必要があります)、IE10 が既に適切に動作していることを考えると、将来問題のある状況が発生するのではないかと心配しています。 . アーキテクチャ的に言えば、アプローチも間違っているようです。

考慮すべきもう 1 つの側面は、モデルをクライアントからサーバーに渡してからクライアントに戻す必要がある場合、「悪い」JavaScript Date オブジェクトを再作成して、アプリケーションのクライアント側。

正しくて拡張可能なソリューションはありません。これまで誰もこの問題に対処する必要がなかったとは信じられません。

他のすべての JavaScript / MVC プロジェクトに適用できる方法で、これを永続的に修正するにはどうすればよいですか?

EDIT #1 - 問題に直接関係のない追加情報:

@matt-johnson が指摘したように、タイムゾーン情報を使用する必要があるケースはほとんどありません。ただし、その場合、被保険者の生年月日は、クライアントがいるタイムゾーンに関連しています。たとえば、ブリティッシュ コロンビア州ビクトリアに住む 17 歳で、誕生日が 12 月 2 日であるとします。彼が 12 月 1 日の 22:00 に保険の見積もりを提出した場合、彼はまだ 17 歳ですが、クライアントのタイムゾーンではすでに 18 歳であるため、保険の見積もりは受け入れられます。同じルールが保険の価格設定にも適用されます。それは法的要件です。

明確にするために、私は他のプロジェクトに適用できる万能なソリューションを探しています。具体的な問題は次のとおりです。Javascript は、2007 年より前の特定の数週間だけ、1 時間のオフセットで時刻を報告します。このオフセットは、時間 (ローカル タイムゾーンまたは UTC) を表現する方法に関係なく、常に存在します。これは、基になるデータ (データ表現ではなく) が間違っているためです。

「時間の部分を正午に設定する」回避策を使用してバグを回避しましたが、根本的な問題はまだ残っています。クライアントが、過去の特定のイベントの日付と時刻を取得する必要がある Web アプリの開発を依頼した場合はどうなりますか? 例: 「事故が発生した正確な日時をお知らせください: 2005 年 10 月 31 日 19:32」. MVC コントローラーは時刻を 18:32 に設定します。

4

1 に答える 1