DateTimeをUTCに変換するときに問題が発生しています 質問する

DateTimeをUTCに変換するときに問題が発生しています 質問する

私はすべての日付を UTC 形式でデータベースに保存しています。ユーザーにタイムゾーンを尋ね、そのタイムゾーンとサーバー時間を使用して UTC を算出したいと考えています。

それができたら、新しく変換された UTC 日付を使用して、データベース内の範囲を確認するための検索を実行します。

しかし、私は常にこの例外を受け取ります。

System.ArgumentException was unhandled by user code  
Message="The conversion could not be completed because the   
supplied DateTime did not have the Kind property set correctly.  
For example, when the Kind property is DateTimeKind.Local,   
the source time zone must be TimeZoneInfo.Local.  
Parameter name: sourceTimeZone"

なぜこのようなことが起こるのか分かりません。

2つの方法を試しました

 TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(id);
 // I also tried DateTime.UtcNow
 DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local); 
 var utc = TimeZoneInfo.ConvertTimeToUtc(now , zone );

これは失敗したので試してみました

 DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local); 
 var utc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, 
                                           ZoneId, TimeZoneInfo.Utc.Id);

これも、同じエラーで失敗しました。何が間違っているのでしょうか?

編集 これは機能しますか?

 DateTime localServerTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
 TimeZoneInfo info = TimeZoneInfo.FindSystemTimeZoneById(id);

 var usersTime = TimeZoneInfo.ConvertTime(localServerTime, info);

 var utc = TimeZoneInfo.ConvertTimeToUtc(usersTime, userInfo);

編集 2 @ ジョン・スキート

はい、私は、これらすべてを行う必要がないかもしれないと考えていました。時間に関することは今私を混乱させているので、投稿がそれほど明確でない可能性があります。DateTime.Now が何を取得しているのかまったくわかりません (タイムゾーンを別のタイムゾーンに変更しようとしましたが、ローカル時間を取得し続けました)。

私が実現したかったのは、次のことです。ユーザーがサイトにアクセスし、アラートを追加すると、utc として保存されます (以前は DateTime.Now でしたが、その後誰かがすべてを UTC で保存することを提案しました)。

つまり、ユーザーが私のサイトにアクセスする前、ホスティング サーバーの場所によっては翌日になる可能性があるということです。つまり、アラートが 8 月 30 日 (現地時間) に表示されるとされていたとしても、サーバーの時差により、ユーザーが 8 月 29 日にアクセスしてアラートが表示される可能性があります。

それで、私はそれに対処したかったのです。だから今は、ローカル時間を保存して、このオフセットを使うべきかどうかわかりません。それとも、UTC 時間だけを保存すべきでしょうか。UTC 時間だけを保存しても、ユーザーはまだローカル時間で考えている可能性が高いので、間違っている可能性があります。UTC が実際にどのように機能するかはわかりません。それでも、時間の差が生じる可能性があります。

編集3

 var info = TimeZoneInfo.FindSystemTimeZoneById(id)

 DateTimeOffset usersTime = TimeZoneInfo.ConvertTime(DataBaseUTCDate,
                                             TimeZoneInfo.Utc, info);

ベストアンサー1

Kindを次のように設定する必要がありますUnspecified

DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified);
var utc = TimeZoneInfo.ConvertTimeToUtc(now , zone);

DateTimeKind.Localはローカルタイムゾーンを意味し、他のタイムゾーンではありません。そのため、エラーが発生していました。

おすすめ記事