C# 强制在应用程序中使用特定时区

C# 强制在应用程序中使用特定时区,c#,asp.net,webforms,timezone,C#,Asp.net,Webforms,Timezone,这里的情况很棘手。我们的应用程序运行在一个设置了特定时区(比如亚洲时间)的系统中。然而,一个客户端请求他的应用程序使用欧洲时区运行 由于我们的数据没有存储在UTC中,我们是否可以在应用程序中设置区域设置,以便显示的所有日期都使用欧洲时区?我知道我们可以在Web.Config上设置文化信息,但我不确定这是否有助于设置时区 顺便说一句,我们的应用程序正在使用C WebForm和MSSQL 2008 R2运行。数据的存储方式与您选择的显示方式完全不同。假设日期和时间表示时间上的固定点,而不是浮动的本地

这里的情况很棘手。我们的应用程序运行在一个设置了特定时区(比如亚洲时间)的系统中。然而,一个客户端请求他的应用程序使用欧洲时区运行

由于我们的数据没有存储在UTC中,我们是否可以在应用程序中设置区域设置,以便显示的所有日期都使用欧洲时区?我知道我们可以在Web.Config上设置文化信息,但我不确定这是否有助于设置时区

顺便说一句,我们的应用程序正在使用C WebForm和MSSQL 2008 R2运行。

数据的存储方式与您选择的显示方式完全不同。假设日期和时间表示时间上的固定点,而不是浮动的本地时间,我会尝试使用UTC的DateTime值尽可能多地编写应用程序。当您检索数据时,如果您没有说明数据存储在哪个时区,请将其从存储时区转换,并在存储数据时将其转换回。当您显示它时,请在您需要的任何时区显示它

就.NET而言,您不需要在全局级别设置此设置-如果确实需要,您可以使用应用程序范围的配置设置,并使用帮助程序代码在需要显示时对其进行转换。不过我会非常明确地这样做:当涉及到时间的事情时,你真的不希望隐式地发生转换

我还要提到的是,我的库在涉及日期和时间时,作为一个更清晰的API可能会很有用。当然,我有偏见。我还建议迁移到UTC中存储所有内容,如果可以的话。。。当然,只有在适当的情况下才能使用。

数据的存储方式与您选择的显示方式完全不同。假设日期和时间表示时间上的固定点,而不是浮动的本地时间,我会尝试使用UTC的DateTime值尽可能多地编写应用程序。当您检索数据时,如果您没有说明数据存储在哪个时区,请将其从存储时区转换,并在存储数据时将其转换回。当您显示它时,请在您需要的任何时区显示它

就.NET而言,您不需要在全局级别设置此设置-如果确实需要,您可以使用应用程序范围的配置设置,并使用帮助程序代码在需要显示时对其进行转换。不过我会非常明确地这样做:当涉及到时间的事情时,你真的不希望隐式地发生转换


我还要提到的是,我的库在涉及日期和时间时,作为一个更清晰的API可能会很有用。当然,我有偏见。我还建议迁移到UTC中存储所有内容,如果可以的话。。。当然,只有在适当的情况下才可以。

您应该将日期存储在:

表示时间点,通常以日期和时间表示 天,相对于协调世界时UTC

使用DateTimeOffset有很大的优势,因为这些日期可以轻松转换为任何时区,而不会丢失事件发生时的偏移量,即在某个时刻存储一些数据

正如Jon Skeet在我的回答中的评论中所建议的那样,时区标识符应该与DateTimeOffset一起存储,以获得完整的日期+时间信息,并使其完全可转换

另一方面,您可能不在特定时区中存储数据,而是使用DateTimeOffset作为整个时区标识符,稍后您将根据用户配置文件或应用程序范围的时区和/或应用程序层中的区域性设置将其转换为所需的时区


最后,您可以使用

转换此类DateTimeOffset。您应该将日期存储在:

表示时间点,通常以日期和时间表示 天,相对于协调世界时UTC

使用DateTimeOffset有很大的优势,因为这些日期可以轻松转换为任何时区,而不会丢失事件发生时的偏移量,即在某个时刻存储一些数据

正如Jon Skeet在我的回答中的评论中所建议的那样,时区标识符应该与DateTimeOffset一起存储,以获得完整的日期+时间信息,并使其完全可转换

另一方面,您可能不在特定时区中存储数据,而是使用DateTimeOffset作为整个时区标识符,稍后您将根据用户配置文件或应用程序范围的时区和/或应用程序层中的区域性设置将其转换为所需的时区


最后,您可以使用

转换这样的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;

换个地方怎么样

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;

谢谢你的建议。但是,我们没有重写代码以将所有内容放入UTC的选项,因为此项目存在时间限制。老实说,我甚至不认为我们有时间来编写helper类
显然是需要的,但是……唉……@ipohfly:好吧,我已经说过我认为最好的做法是什么了。如果没有对项目和时间限制的详细了解,就很难说你应该走多少捷径。不过,我会非常小心那些不能解决根本问题的短期解决方案。谢谢。另一个问题是,即使我将所有日期存储在UTC中,并在显示时将其格式化为本地时间,RDLC报告中显示的数据如何?这也可以实现吗?谢谢你的意见:@ipohfly:恐怕我对RDLC报告一无所知。我当然希望他们可以调整,因为这一定是一个非常普遍的要求。谢谢你的建议。但是,我们没有重写代码以将所有内容放入UTC的选项,因为此项目存在时间限制。老实说,我甚至不认为我们有时间编写显然需要的helper类,但是..叹气..@ipohfly:好吧,我已经说过我认为最好的做法是什么了。如果没有对项目和时间限制的详细了解,就很难说你应该走多少捷径。不过,我会非常小心那些不能解决根本问题的短期解决方案。谢谢。另一个问题是,即使我将所有日期存储在UTC中,并在显示时将其格式化为本地时间,RDLC报告中显示的数据如何?这也可以实现吗?谢谢你的意见:@ipohfly:恐怕我对RDLC报告一无所知。我当然希望可以对它们进行调整,因为这必须是一个非常常见的要求。请参阅。链接这将有助于你@谢谢你的链接。链接这将有助于你@Niks感谢linkDateTimeOffset确实丢失了事件发生的时区。它不会丢失本地时间,但会丢失时区。在任何一个时间点上都可以有多个时区使用相同的偏移量。@JonSkeet一般来说,它不会丢失偏移量。时区是一个极其复杂的问题,我知道我读过很多文章,包括你的一些D.根据进入你网站的人口统计数据,DateTimeOffset就足够了,你认为呢?一般来说,它肯定会失去它。在某些特定情况下,可能不是这样。但是如果你真的关心时区,你应该知道并储存它。如果您只关心当时的本地时间,那么DateTimeOffset就可以了。我并不是说DateTimeOffset总是不合适的-尽管在很多情况下你真的不需要知道原始的本地时间,UTC日期时间也可以-我主要反对你的说法,即它不会丢失时区。请参阅,以获取一些代码,显示时区的数量,即使在相当小的Windows DB中,也可以观察到当前的任何特定偏移。@JonSkeet感谢你的努力,我会在不到一小时内检查你的评论和示例代码,我正在吃早餐!!。谢谢DateTimeOffset会丢失事件发生的时区。它不会丢失本地时间,但会丢失时区。在任何一个时间点上都可以有多个时区使用相同的偏移量。@JonSkeet一般来说,它不会丢失偏移量。时区是一个极其复杂的问题,我知道我读过很多文章,包括你的一些D.根据进入你网站的人口统计数据,DateTimeOffset就足够了,你认为呢?一般来说,它肯定会失去它。在某些特定情况下,可能不是这样。但是如果你真的关心时区,你应该知道并储存它。如果您只关心当时的本地时间,那么DateTimeOffset就可以了。我并不是说DateTimeOffset总是不合适的-尽管在很多情况下你真的不需要知道原始的本地时间,UTC日期时间也可以-我主要反对你的说法,即它不会丢失时区。请参阅,以获取一些代码,显示时区的数量,即使在相当小的Windows DB中,也可以观察到当前的任何特定偏移。@JonSkeet感谢你的努力,我会在不到一小时内检查你的评论和示例代码,我正在吃早餐!!。谢谢