Webサービスクライアント用のC#アプリケーションを開発しています。これはWindows XP PC上で動作します。
Webサービスによって返されるフィールドの1つはDateTimeフィールドです。サーバーはGMTフォーマットのフィールド、すなわち末尾に "Z"を付けて返します。
しかし、.NETはある種の暗黙的な変換を実行しているように見え、時間は常に12時間ずれています。
次のコードサンプルは、12時間の差がなくなったという点である程度この問題を解決していますが、ニュージーランドの夏時間は考慮されていません。
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のある種の設定ですか?
2012-09-19 01:27:30.000
のような文字列の場合、DateTime.Parse
は日付と時刻がどのタイムゾーンのものであるかを知ることができません。
DateTime
にはKindプロパティがあり、3つのタイムゾーンオプションのうちの1つを持つことができます。
NOTEUTCまたはあなたの地域のタイムゾーン以外の日付/時刻を表したい場合は、 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();
これにより、必要な結果が得られます。
あなたが.NET 3.5にいるならば、私はSystem.TimeZoneInfoクラスを使うことになるでしょう。 http://msdn.Microsoft.com/ja-jp/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);
TimeZone.CurrentTimeZone.ToLocalTime(date);
DateTime
オブジェクトはデフォルトでKind
のUnspecified
を持ちます。これはToLocalTime
の目的のためにUTC
と見なされます。
Unspecified
DateTime
オブジェクトの現地時間を取得するには、こうするだけです:
convertedDate.ToLocalTime();
Kind
のDateTime
をUnspecified
からUTC
に変更するステップは不要です。 Unspecified
は、UTC
の目的でToLocalTime
と見なされます。 http://msdn.Microsoft.com/ja-jp/library/system.datetime.tolocaltime.aspx
私はこれがより古い質問であることを知っています、しかし、私は同様の状況に遭遇しました、そして私は私自身を含むこともあるかもしれません。
DateTime.Parse()
は扱いにくいかもしれません - 例えばここで を見てください 。
DateTime
がWebサービスまたはその他の既知の形式のソースから来ている場合は、次のようなものを検討します。
DateTime.ParseExact(dateString,
"MM/dd/yyyy HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
あるいは、もっと良い
DateTime.TryParseExact(...)
AssumeUniversal
フラグは、日付/時刻がすでにUTCであることをパーサーに伝えます。 AssumeUniversal
とAdjustToUniversal
の組み合わせは、結果を「現地時間」に変換しないように指示します。これはデフォルトで行われます。 (私は個人的にはとにかくビジネス/アプリケーション/サービス層でUTCを扱うようにしています。しかし現地時間への変換を回避することは物事をスピードアップします - 私のテストでは50%以上、以下を見てください。)
これが私たちが以前やっていたことです。
DateTime.Parse(dateString, new CultureInfo("en-US"))
アプリをプロファイリングしたところ、DateTime.ParseがCPU使用率のかなりの割合を占めていることがわかりました。 (ちなみに、CultureInfo
コンストラクタはCPU使用率への重要な貢献者ではありませんでした。)
そこで、私はさまざまな方法で日付/時刻文字列を10000回解析するようにコンソールアプリを設定しました。一番下の行Parse()
10秒ParseExact()
(ローカルに変換)20-45ミリ秒ParseExact()
(ローカルには変換されません)10-15 ms
...そしてそうです、Parse()
の結果は秒ですが、他の結果はミリ秒です。
一般的な注意を追加したいだけです。
あなたがしているのがディスプレイまたはレポートに日付/時刻を置くためにコンピュータの内部時計から現在の時刻を得ることだけであれば、それですべてうまくいきます。しかしあなたが 節約 後で参照するための日時情報 コンピューティング 日付/時間、用心しなさい!
クルーズ船が2007年12月20日のUTC 15:00にホノルルに到着したと判断したとしましょう。そして、あなたはそれがどの現地時間であるか知りたいのです。
1。 おそらく少なくとも3人の「地元の人々」が関わっています。ローカルはホノルルを意味するかもしれません、またはそれはあなたのコンピュータがある場所を意味するかもしれません、またはそれはあなたの顧客がいる場所を意味するかもしれません。
2。 あなたが変換をするために組み込み関数を使うならば、それはおそらく間違っているでしょう。これは、夏時間が(おそらく)現在コンピュータに有効であるが、12月に有効ではなかったためです。しかし、Windowsはこれを知りません...それが持っているのは、夏時間が現在有効であるかどうかを判断するためのフラグです。そしてそれが現在有効であれば、それはそれから12月の日付にさえ1時間を幸せに追加するでしょう。
3。 サマータイムは、さまざまな政治区分で異なる方法で(またはまったく実施されていない)実装されています。あなたの国が特定の日に変わったからといって、他の国にも変わるとは思わないでください。
DateTimeオブジェクトをすでに持っていて、それがUTCかLocalかどうかわからない場合は、忘れないでください。オブジェクトのメソッドを直接使用するのは簡単です。
DateTime convertedDate = DateTime.Parse(date);
DateTime localDate = convertedDate.ToLocalTime();
余分な時間をどのように調整しますか?
指定しない限り、.netはローカルのPC設定を使用します。 http://msdn.Microsoft.com/ja-jp/library/system.globalization.daylighttime.aspx
見た目では、コードは次のようになります。
DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );
そして上で述べたように、あなたのサーバーがどのタイムゾーン設定になっているかを二重にチェックしてください。安全にIISの変更に影響を与える方法についてのネット上の記事があります。
@TimeZoneInfo.ConvertTimeFromUtc(timeUtc, TimeZoneInfo.Local)
Danaの提案に答えて
コードサンプルは次のようになりました。
string date = "Web service date"..ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);
元の日付は20/08/08でした。種類はUTCでした。
"conversionDate"と "dt"は同じです。
21/08/08 10:00:26;地元の人
あなたがTwitter APIを介して返されるUTCの日付(ステータスのcreated_atフィールド)に問題があったので、私はこの質問に出会いました。それらをDateTimeに変換する必要があります。このページの回答の中の回答/コードサンプルのどれも、「文字列は有効なDateTimeとして認識されませんでした」というエラーが表示されるのを防ぐのに十分ではありませんでした。
これが他の誰かを助ける場合に備えてこのリンクをここに投稿する - 私が必要とする答えはこのブログ記事で見つかりました: http://www.wduffy.co.uk/blog/parsing-dates-when -aspnets-datetimeparse-doesnt-work / - 基本的には、DateTime.Parseの代わりにフォーマット文字列を使用してDateTime.ParseExactを使用します。
DataColumnのDateTypeフィールドがlocalに設定されているために自動的に変更されるという、データセットがネットワークを介してプッシュされるという問題がありました(Webサービスからクライアントへ)。データセットをプッシュする場合は、必ずDateTypeを確認してください。
変更したくない場合は、Unspecifiedに設定します。