.NET 3.5 での DateTime シリアル化のベスト プラクティス
-
09-06-2019 - |
質問
4年ほど前、私はこれに従いました MSDN の記事 DateTime の使用方法については、.Net 1.1 および ASMX Web サービス (バックエンドとして SQL 2000 サーバーを使用) 上で .Net クライアントを構築するためのベスト プラクティスについて説明します。DateTime で発生したシリアル化の問題と、異なるタイム ゾーンのサーバーに対してテストに要した労力を今でも覚えています。
私の質問は次のとおりです。WCF や SQL Server 2008 などの一部の新しいテクノロジ、特にタイム ゾーン対応情報を格納するための新しい日時型の追加について、同様のベスト プラクティス ドキュメントはありますか。
環境は次のとおりです。
- SQL Server 2008 (太平洋時間)。
- 異なるタイムゾーンの Web サービス層。
- クライアントは、異なるタイム ゾーンで .Net 2.0 または .Net 3.5 を使用している可能性があります。それが簡単にできるのであれば、全員に .Net 3.5 へのアップグレードを強制することができます。:)
各レイヤーで使用されるデータ型に関する良い提案/ベスト プラクティスはありますか?
解決
これを行う最善の方法は、オブジェクトを常に UTC として渡し、クライアントで現地時間に変換することだと思います。そうすることで、すべてのクライアントに共通の参照点が存在します。
UTC に変換するには、DateTime オブジェクトで ToUniversalTime を呼び出します。次に、クライアント上で ToLocalTime を呼び出して、現在のタイム ゾーンで取得します。
他のヒント
大きな問題の 1 つは、WCF シリアル化が xs:Date をサポートしていないことです。これは大きな問題です。日付さえあればいいのですから、タイムゾーンを気にする必要はないのです。次の接続の問題では、いくつかの問題について説明します。 http://connect.microsoft.com/wcf/フィードバック/ViewFeedback.aspx?FeedbackID=349215
ある時点を明確に表現したい場合、つまりクライアントとサーバーの両方に .NET 3.5 がある場合は、日付部分だけでなく、DateTimeOffset クラスも使用できます。または、相互運用性を確保するために、日付/時刻値を常に UTC として渡します。
UTC/GMT は分散環境では一貫しています。
重要なことの 1 つは、DateTime プロパティにデータベースの値を設定した後で datetimeKind を指定することです。
dateTimeValueUtcKind = DateTime.SpecifyKind(dateTimeValue, DateTimeKind.Utc);
Web サービス層とクライアント層が .NET DateTime 型を使用している限り、次のようなタイムゾーン情報を含む SOAP 標準のローカル日付/時刻として適切にシリアル化および逆シリアル化する必要があります。
09/15/2008 20:14:36
絶対に、確実にタイムゾーン自体を知る必要がある場合(つまり、上記は東部標準時または中部夏時間の可能性があります)、それらの部分をそのように公開する独自のデータ型を作成する必要があります。
[Serializable]
public sealed class MyDateTime
{
public MyDateTime()
{
this.Now = DateTime.Now;
this.IsDaylightSavingTime = this.Now.IsDaylightSavingTime();
this.TimeZone = this.IsDaylightSavingTime
? System.TimeZone.CurrentTimeZone.DaylightName
: System.TimeZone.CurrentTimeZone.StandardName;
}
public DateTime Now
{
get;
set;
}
public string TimeZone
{
get;
set;
}
public bool IsDaylightSavingTime
{
get;
set;
}
}
その場合、応答は次のようになります。
<Now>2008-09-15T13:34:08.0039447-05:00</Now>
<TimeZone>Central Daylight Time</TimeZone>
<IsDaylightSavingTime>true</IsDaylightSavingTime>
DateTime データ型をそのまま維持し、常に GMT として保存することができて幸運でした。各レイヤーで、GMT 値をレイヤーのローカル値に調整します。