11

JSON シリアル化オブジェクトを使用して、クライアントのブラウザーに正しい日付を表示する際に問題が発生しています。ユーザーは、データを表示するタイム ゾーンを定義できます。これを考慮して、UTC 日付をサーバー上のユーザーのタイム ゾーンに変換します。次に、日付/時刻 (定義済みのタイム ゾーンに既に変換されています) を JSON 経由でブラウザーにシリアル化したいと思います。

単純なように思えますが、私が使用してきた JSON シリアライザーは私の日付をひどく混乱させてきました。サーバーは UTC で、クライアントは中央 (-6) です。DateTime.Kind を Unspecified に指定しているにもかかわらず、日付が調整されています (-12 時間)。

どういうわけか、.NET はクライアントのブラウザーのタイム ゾーンとサーバーのタイム ゾーンを認識しており、ユーザーのグローバル設定に従って時刻を調整して日付を設定しているにもかかわらず、日付/時刻から -6 を否定しています。未指定の種類。JSONシリアライザーが日付を調整しようとしないようにするにはどうすればよいですか?

List<ErrorGridModel> models = Mapper.Map<ErrorCollection, List<ErrorGridModel>>(errors);
foreach (ErrorGridModel m in models)
{
    //convert UTC dates to user local dateTime - split out date vs. time for grouping & splitting columns
    DateTime dtLocal = TimeZoneInfo.ConvertTimeFromUtc(m.ErrorDate, this.AppContext.User.TimeZoneInfo);
    m.ErrorDate = new DateTime(dtLocal.Year, dtLocal.Month, dtLocal.Day, 0, 0, 0, DateTimeKind.Unspecified);
    m.ErrorTime = new DateTime(1900, 1, 1, dtLocal.Hour, dtLocal.Minute, dtLocal.Second, DateTimeKind.Unspecified);
}
IQueryable<ErrorGridModel> dataSource = models.AsQueryable();
return new ContentResult() { Content = JsonConvert.SerializeObject(dataSource.ToDataSourceResult(request), new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }), ContentType = "application/json" };
//return Json(dataSource.ToDataSourceResult(request));

ISO日付は機能しているように見えますが、サードパーティのコントロールが古いMicrosoft形式を必要とするため、それらを使用できません...これによりタイムゾーンが調整されます。

4

3 に答える 3

4

オフセットを制御しようとしている場合は、に依存しないでくださいDateTimeKind.Unspecified。と解釈されることが多いいくつかの癖がありUnspecified == Localます。Json.Net に (ISO または MS 形式に関係なく) 正しいオフセットを明確にエンコードさせる唯一の方法は、. のDateTimeOffset代わりに aを渡すことDateTimeです。

// Start with the UTC time, for example your m.ErrorDate.
// Here I demonstrate with UtcNow.  Any DateTime with .Kind = UTC is ok.
var dt = DateTime.UtcNow;

// Use the appropriate time zone, here I demonstrate with EST.
var tzi = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

// Get the offset from UTC for the time zone and date in question.
var offset = tzi.GetUtcOffset(dt);

// Get a DateTimeOffset for the date, and adjust it to the offset found above.
var dto = new DateTimeOffset(dt).ToOffset(offset);

// Serialize to json
var json = JsonConvert.SerializeObject(dto, new JsonSerializerSettings
    {
        DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
    });


// The json should now contain the correct time and offset information.
// For example,  "\/Date(1358789156229-0500)\/"

これで、使用している JavaScript コントロールがオフセットを尊重し、適切に適用することがわかると思います。そうでない場合、残りの問題は使用しているコントロールに固有のものです。

于 2013-01-21T17:29:31.077 に答える
2

これは、私が経験した正確な状況に関する長い議論です。 http://www.telerik.com/community/forums/aspnet-mvc/grid/grids-and-dates.aspx

要するに、Microsoft JSON 日付形式を使用している場合、日付は常に 1970 年 1 月 1 日 UTC からのミリ秒数 (ティック) として UTC で反映されます。Kendo Grid コントロールは JS の目盛りから日付を UTC としてインスタンス化するため、サーバー上で時間をローカルに自動変換し、JSON を介して Kendo Grid に送信する方法はありません。この日付を表示すると、値がブラウザのローカル タイム ゾーンに自動変換されます。

サーバーから変換されたサーバーの日付値を表示する唯一の方法は、JSON を介して日付を文字列としてクライアントに送信することです。

于 2013-01-22T01:27:52.087 に答える
0

この問題にも遭遇しました。お気づきのように、問題は実際にはクライアント側で発生しています。グリッドでリクエスト終了ハンドラを使用すると、日付を UTC に戻すことができます。ここにある例:

http://www.kendoui.c​​om/code-library/mvc/grid/using-utc-time-on-both-client-and-server-sides.aspx

于 2013-03-05T22:06:58.923 に答える