2012-08-12 26 views
5

用户在单独的文本框中输入日期和时间。然后我将日期和时间合并到一个日期时间。我需要将此日期时间转换为UTC以将其保存在数据库中。我将用户的时区ID保存在数据库中(他们在注册时选择它)。首先,我试过如下:将用户输入的UTC转换为UTC

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

然后我尝试设置一种属性,像这样:

DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Local); 

这并没有工作,所以我试过了:

DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Unspecified); 

这也没有工作。任何人都可以解释我需要做什么?我甚至会以正确的方式去解决这个问题吗?我应该使用DateTimeOffset吗?

+0

[转换本地时间UTC在.NET框架3.0]可能重复(http://stackoverflow.com/questions/4668921/convert-local-time -to-utc-in-net-framework-3-0) – Shai 2012-08-12 06:58:10

+0

@Shai:显然不是重复的,因为这个问题有:“我必须在.NET Framework 3.0中使用,所以不能使用TimeZoneInfo对象。” – 2012-08-12 07:02:37

+0

@JonSkeet Ahhh没有看到,可能会给OP一个主角.. – Shai 2012-08-12 07:19:00

回答

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的变化。

+0

谢谢乔恩!简直不敢相信!我会看看野田时间,因为它看起来更简单易用! – HTX9 2012-08-12 07:22:23

+0

@ HTX9:Goodo - 你可能会发现最初它实际上感觉更复杂,因为它迫使你真正弄清楚你得到了什么样的数据(本地,日期与时间和日期/时间),如何处理模糊等。这些都是你应该一直在想的东西,但是.NET API很难发现它们。无论如何,这就是理论:) – 2012-08-12 07:30:13

1

你也可以试试这个

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