C# 将用户输入的日期时间转换为 UTC
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11920312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert datetime entered by user to UTC
提问by HTX9
The user enters a date and a time in separate textboxes. I then combine the date and time into a datetime. I need to convert this datetime to UTC to save it in the database. I have the user's time zone id saved in the database (they select it when they register). First, I tried the following:
用户在单独的文本框中输入日期和时间。然后我将日期和时间组合成一个日期时间。我需要将此日期时间转换为 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);
This resulted in an exception:
这导致了一个异常:
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
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
I then tried setting the Kind property like so:
然后我尝试像这样设置 Kind 属性:
DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Local);
This didn't work, so I tried:
这不起作用,所以我尝试了:
DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Unspecified);
This didn't work either. Can anyone explain what I need to do? Am I even going about this the correct way? Should I be using DateTimeOffset?
这也不起作用。谁能解释一下我需要做什么?我什至以正确的方式解决这个问题吗?我应该使用 DateTimeOffset 吗?
采纳答案by Jon Skeet
Just like all the other methods on DateTime, SpecifyKinddoesn't change an existingvalue - it returns a newvalue. You need:
就像 上的所有其他方法一样DateTime,SpecifyKind不会更改现有值 - 它返回一个新值。你需要:
combinedDateTime = DateTime.SpecifyKind(combinedDateTime,
DateTimeKind.Unspecified);
Personally I'd recommend using Noda Timewhich makes this kind of thing rather clearer in my rather biased view (I'm the main author). You'd end up with this code instead:
就我个人而言,我建议使用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...
The "leniently" part is because when you convert local times to a specific zone, there's the possibility for the local value being invalid or ambiguous in the time zone due to DST changes.
“宽松”部分是因为当您将本地时间转换为特定区域时,由于 DST 更改,时区中的本地值可能无效或不明确。
回答by geekbytes0xff
You can also try this
你也可以试试这个
var combinedLocalTime = new DateTime((dateOnly + timeOnly.TimeOfDay).Ticks,DateTimeKind.Local);
var utcTime = combinedLocalTime.ToUniversalTime();

