5

用户在单独的文本框中输入日期和时间。然后我将日期和时间组合成一个日期时间。我需要将此日期时间转换为 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

就像 上的所有其他方法一样DateTimeSpecifyKind不会更改现有值 - 它返回一个值。你需要:

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 回答