【问题标题】:Convert datetime entered by user to UTC将用户输入的日期时间转换为 UTC
【发布时间】:2012-08-08 20:33:19
【问题描述】:

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

【问题讨论】:

  • @Shai:显然不是重复的,因为那个问题有:“我必须在 .NET framework 3.0 中使用,所以不能使用 TimeZoneInfo 对象。”
  • @JonSkeet Ahhh 没有看到这一点,但可能会给 OP 带来领先......

标签: c# datetime timezone


【解决方案1】:

就像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 更改,本地值可能在时区中无效或不明确。

【讨论】:

  • 谢谢乔恩!不敢相信它是那么简单!我会查看 Noda Time,因为它看起来更易于使用!
  • @HTX9:Goodo - 你可能会发现最初它实际上感觉更复杂,因为它迫使你实际计算出你拥有什么样的数据(本地,日期 vs 时间 vs 日期/时间)、如何处理歧义等。无论如何,这些都是您应该考虑的事情,但是 .NET API 使得发现它们变得更加困难。无论如何,这就是理论:)
【解决方案2】:

你也可以试试这个

var combinedLocalTime = new DateTime((dateOnly + timeOnly.TimeOfDay).Ticks,DateTimeKind.Local);
var utcTime = combinedLocalTime.ToUniversalTime();

【讨论】:

    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2011-01-06
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多