324

Web サービス クライアント用の C# アプリケーションを開発しています。これは、Windows XP PC で実行されます。

Web サービスから返されるフィールドの 1 つに DateTime フィールドがあります。サーバーはフィールドを GMT 形式、つまり末尾に「Z」を付けて返します。

しかし、.NET はある種の暗黙的な変換を行っているようで、時間は常に 12 時間遅れていることがわかりました。

次のコード サンプルでは、​​12 時間の差はなくなりましたが、NZ の夏時間は考慮されていないため、これをある程度解決しています。

CultureInfo ci = new CultureInfo("en-NZ");
string date = "Web service date".ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);            

この日付サイトによると:

UTC/GMT オフセット

標準タイム ゾーン: UTC/GMT +12 時間
サマータイム: +1 時間
現在のタイム ゾーン オフセット: UTC/GMT +13 時間

余分な時間をどのように調整しますか?これはプログラムで実行できますか、それとも PC の設定のようなものですか?

4

12 に答える 12

395

などの文字列の場合2012-09-19 01:27:30.000DateTime.Parse日付と時刻がどのタイム ゾーンからのものかわかりません。

DateTimeKindプロパティがあり、次の 3 つのタイム ゾーン オプションのいずれかを指定できます。

  • 不明
  • ローカル
  • UTC

: UTC またはローカル タイム ゾーン以外の日付/時刻を表す場合は、 を使用する必要がありますDateTimeOffset


したがって、質問のコードについては:

DateTime convertedDate = DateTime.Parse(dateStr);

var kind = convertedDate.Kind; // will equal DateTimeKind.Unspecified

あなたはそれがどんな種類か知っていると言うので、それを教えてください。

DateTime convertedDate = DateTime.SpecifyKind(
    DateTime.Parse(dateStr),
    DateTimeKind.Utc);

var kind = convertedDate.Kind; // will equal DateTimeKind.Utc

これで、システムが UTC 時間を認識したら、次のように呼び出すことができますToLocalTime

DateTime dt = convertedDate.ToLocalTime();

これにより、必要な結果が得られます。

于 2009-06-08T07:43:37.160 に答える
125

.NET 3.5 を使用している場合は、System.TimeZoneInfo クラスの使用を検討します。http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspxを参照してください。これは、夏時間の変更を正しく考慮に入れる必要があります。

// Coordinated Universal Time string from 
// DateTime.Now.ToUniversalTime().ToString("u");
string date = "2009-02-25 16:13:00Z"; 
// Local .NET timeZone.
DateTime localDateTime = DateTime.Parse(date); 
DateTime utcDateTime = localDateTime.ToUniversalTime();

// ID from: 
// "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zone"
// See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.id.aspx
string nzTimeZoneKey = "New Zealand Standard Time";
TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(nzTimeZoneKey);
DateTime nzDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);
于 2009-01-18T21:50:49.100 に答える
63
TimeZone.CurrentTimeZone.ToLocalTime(date);
于 2008-10-07T19:29:47.013 に答える
29

DateTimeオブジェクトにはKindデフォルトUnspecifiedでのがあり、の目的でToLocalTimeは。と見なされますUTC

したがって、オブジェクトの現地時間を取得するには、次のUnspecified DateTimeようにする必要があります。

convertedDate.ToLocalTime();

KindのをDateTimeからUnspecifiedに変更する手順UTCは不要です。http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspxの目的であるUnspecifiedと想定されていますUTCToLocalTime

于 2012-11-16T03:51:35.413 に答える
16

これは古い質問であることは知っていますが、同様の状況に遭遇したため、おそらく私自身を含め、将来の検索者のために見つけたことを共有したいと思いました:)。

DateTime.Parse()トリッキーな場合があります-たとえば、ここを参照してください。

DateTimeが Web サービスまたは既知の形式の他のソースからのものである 場合は、次のようなものを検討することをお勧めします。

DateTime.ParseExact(dateString, 
                   "MM/dd/yyyy HH:mm:ss", 
                   CultureInfo.InvariantCulture, 
                   DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)

または、さらに良いことに、

DateTime.TryParseExact(...)

このAssumeUniversalフラグは、日付/時刻がすでに UTC であることをパーサーに伝えます。と の組み合わせは、結果を「ローカル」時間に変換しないようAssumeUniversalAdjustToUniversal指示します。これは、デフォルトで実行しようとします。(個人的には、ビジネス/アプリケーション/サービス層で UTC のみを扱うようにしています。しかし、現地時間への変換をバイパスすると、速度も向上します。私のテストでは、50% 以上のスピードが得られます。以下を参照してください。)

以前に行っていたことは次のとおりです。

DateTime.Parse(dateString, new CultureInfo("en-US"))

アプリのプロファイリングを行ったところ、DateTime.Parse が CPU 使用率のかなりの割合を占めていることがわかりました。(ちなみに、CultureInfoコンストラクターはCPU 使用率に大きな影響を与え ませんでした。)

そこで、さまざまな方法で日付/時刻文字列を 10000 回解析するコンソール アプリをセットアップしました。結論:
Parse()10 秒
ParseExact()(ローカルに変換) 20 ~ 45 ミリ秒
ParseExact()(ローカルに変換しない) 10 ~ 15 ミリ秒
... はい、結果Parse()単位ですが、他の結果はミリ秒単位です。

于 2011-10-26T16:10:55.060 に答える
15

一般的な注意点を追加したいと思います。

コンピューターの内部時計から現在の時刻を取得して日付/時刻をディスプレイまたはレポートに表示するだけであれば、すべて問題ありません。ただし、後で参照できるように日付/時刻情報を保存する場合、または日付/時刻を計算する場合は、注意してください。

クルーズ船が2007年12月20日15:00UTCにホノルルに到着したと仮定します。そして、あなたはそれが何時だったか知りたいです。
1.おそらく少なくとも3つの「地元の人々」が関わっています。ローカルとはホノルルを意味する場合もあれば、コンピューターが配置されている場所を意味する場合もあります。または、顧客が配置されている場所を意味する場合もあります。
2.組み込み関数を使用して変換を行う場合は、おそらく間違っています。これは、夏時間が(おそらく)現在コンピュータで有効になっているが、12月には有効ではなかったためです。しかし、Windowsはこれを認識していません...夏時間が現在有効であるかどうかを判断するためのフラグが1つだけあります。そして、それが現在有効であるならば、それは12月の日付にさえ幸いにも1時間を追加するでしょう。
3.3。夏時間は、さまざまな政治的細分化で異なる​​方法で(またはまったく)実装されません。あなたの国が特定の日に変わるからといって、他の国も変わるとは思わないでください。

于 2008-10-08T12:21:02.743 に答える
5

すでにDateTimeオブジェクトがあり、それがUTCなのかローカルなのかわからない場合は、オブジェクトのメソッドを直接使用するのは簡単です。

DateTime convertedDate = DateTime.Parse(date);
DateTime localDate = convertedDate.ToLocalTime();

余分な時間をどのように調整しますか?

指定されていない限り、.netはローカルPC設定を使用します。http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspxを読んでください。

見た目では、コードは次のようになります。

DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );

また、上記のように、サーバーがオンになっているタイムゾーン設定を再確認してください。IISの変更に安全に影響を与える方法については、ネット上に記事があります。

于 2008-10-08T12:48:24.343 に答える
4

ダナの提案に答えて:

コード サンプルは次のようになります。

string date = "Web service date"..ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);            
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);

元の日付は 2008 年 8 月 20 日でした。種類は UTC でした。

「convertedDate」と「dt」は同じです。

21/08/08 10:00:26; 種類はローカルでした

于 2008-10-07T19:55:26.277 に答える
1

Twitter API(ステータスのcreated_atフィールド)を介して返されるUTC日付に問題があったため、この質問に出くわしました。それらをDateTimeに変換する必要があります。このページの回答の回答/コード サンプルのどれも、「文字列が有効な DateTime として認識されませんでした」というエラーが発生するのを止めるのに十分ではありませんでした (ただし、SO で正しい回答を見つけるのに最も近いものです)。

これが他の誰かに役立つ場合に備えて、このリンクをここに投稿します-必要な答えは、このブログ投稿で見つかりました: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ -基本的に、DateTime.Parseの代わりにフォーマット文字列でDateTime.ParseExactを使用します

于 2009-10-03T16:01:31.207 に答える
1

DataColumn の DateType フィールドが local に設定されているため、データセットがワイヤ (Web サービスからクライアント) を介してプッシュされているため、自動的に変更されるという問題がありました。DataSet をプッシュする場合は、DateType が何であるかを確認してください。

変更したくない場合は、Unspecified に設定します。

于 2008-10-07T19:59:08.547 に答える