这里的情况很棘手。我们的应用程序运行在一个设置了特定时区(比如亚洲时间)的系统中。然而,客户端要求他的应用程序使用欧洲时区运行。
由于我们的数据不是用UTC存储的,我们是否可以在应用程序中设置区域设置,以便所有显示的日期都使用欧洲时区?我知道我们可以在网上设置文化信息。配置,但我不确定是否可以帮助设置时区以及
顺便说一下,我们的应用程序是使用c# WebForm和MSSQL 2008 R2运行的。
您的数据如何存储与您选择如何显示完全不同。假设日期和时间表示固定的时间点(而不是浮动的"本地"时间),我会尝试尽可能多地使用UTC的DateTime
值编写应用程序。检索数据时,如果需要,可以从"存储时区"转换数据(您没有说数据存储在哪个区域),并在存储时将其转换回来。当您显示时,请将其显示在您需要的任何时区。
就. net而言,你不需要在全局级别设置它——你可以有一个应用程序范围的配置设置(如果你真的想的话)和"助手"代码来转换它,当你需要显示时。但我会非常明确地这样做:当涉及到时间的东西时,你真的不希望转换隐式地发生。
(我还想提一下,当涉及到日期和时间时,我的Noda Time库可能会作为一个更清晰的API而有用。当然,我有偏见。如果可以的话,我还建议迁移到将所有内容存储在UTC中……当然,只在适当的时候。)
您应该使用DateTimeOffset
存储您的日期:
表示一个时间点,通常表示为日期和时间天,相对于协调世界时(UTC)
使用DateTimeOffset
有很大的优势,因为这些日期很容易转换到任何时区,而不会丢失事件发生的偏移量(即在某个时刻存储一些数据)。
正如Jon Skeet在我的回答的评论中建议的那样,时区标识符应该与DateTimeOffset
一起存储,以便拥有完整的日期+时间信息并使其完全可转换。
DateTimeOffset
作为时区标识符,然后根据用户配置文件或应用程序范围的时区和/或应用层中的文化设置将其转换为所需的时区。
最后,您可以使用这个TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo)
重载转换这样的DateTimeOffset
。
如何更改区域设置?
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
if (currentCulture.Name != "sv-SE")
{
// Change the current culture to sv-SE and serialize the date.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("sv-SE");
}
// Do something with a date in swedish timeZone
var swedishNow = DateTime.Now;
// Restore back to the original culture, when finished
Thread.CurrentThread.CurrentCulture = currentCulture;