5

ユーザーは、日付と時刻を別々のテキスト ボックスに入力します。次に、日付と時刻を結合して datetime にします。データベースに保存するには、この日時を UTC に変換する必要があります。ユーザーのタイムゾーンIDをデータベースに保存しています(登録時に選択します)。まず、次のことを試しました。

string userTimeZoneID = "sometimezone"; // Retrieved from database
TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(userTimeZoneID);

DateTime dateOnly = someDate;
DateTime timeOnly = someTime;
DateTime combinedDateTime = dateOnly.Add(timeOnly.TimeOfDay);
DateTime convertedTime = TimeZoneInfo.ConvertTimeToUtc(combinedDateTime, userTimeZone);

これにより、例外が発生しました。

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

次に、Kind プロパティを次のように設定してみました。

DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Local);

これはうまくいかなかったので、私は試しました:

DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Unspecified);

これもうまくいきませんでした。誰が私が何をする必要があるか説明できますか? 私はこれを正しい方法で行っていますか?DateTimeOffset を使用する必要がありますか?

4

2 に答える 2

7

の他のすべてのメソッドと同様にDateTime既存のSpecifyKind値を変更せず、新しい値を返します。必要なもの:

combinedDateTime = DateTime.SpecifyKind(combinedDateTime,
                                        DateTimeKind.Unspecified);

個人的には、私のかなり偏った見解では、この種のことをより明確にするNoda Timeを使用することをお勧めします (私は主な著者です)。代わりに、次のコードになります。

DateTimeZone zone = ...;
LocalDate date = ...;
LocalTime time = ...;
LocalDateTime combined = date + time;
ZonedDateTime zoned = combined.InZoneLeniently(zone);
// You can now get the "Instant", or convert to UTC, or whatever...

「寛大」な部分は、現地時間を特定のゾーンに変換するときに、DST の変更によりタイム ゾーンでローカル値が無効またはあいまいになる可能性があるためです。

于 2012-08-12T07:00:50.047 に答える
1

これを試すこともできます

var combinedLocalTime = new DateTime((dateOnly + timeOnly.TimeOfDay).Ticks,DateTimeKind.Local);
var utcTime = combinedLocalTime.ToUniversalTime();
于 2012-08-12T09:21:41.163 に答える