根据存储的时区修改ASP.NET MVC#中的日期

根据存储的时区修改ASP.NET MVC#中的日期,c#,.net,asp.net-mvc,linq,linq-to-entities,C#,.net,Asp.net Mvc,Linq,Linq To Entities,我的问题有两个方面 1) 我正在编写一个论坛的代码,我很难找到如何为论坛用户存储时区的方法。他们将能够设置自己的时区,并相应地修改论坛上的所有日期。我是否必须创建一个带有时区名称和数字的DB表来调整服务器时间?NET是否有内置的时区支持 2) 一旦我知道如何存储用户的时区,然后将DateTime对象修改到正确的时间,我就需要一种简单的方法将修改后的日期传递到MVC中的视图。例如,我有以下代码: List<Topic> topics = board.Topics.OrderByDesc

我的问题有两个方面

1) 我正在编写一个论坛的代码,我很难找到如何为论坛用户存储时区的方法。他们将能够设置自己的时区,并相应地修改论坛上的所有日期。我是否必须创建一个带有时区名称和数字的DB表来调整服务器时间?NET是否有内置的时区支持

2) 一旦我知道如何存储用户的时区,然后将DateTime对象修改到正确的时间,我就需要一种简单的方法将修改后的日期传递到MVC中的视图。例如,我有以下代码:

List<Topic> topics = board.Topics.OrderByDescending(x => x.Replies.Any() 
                                                    ? x.Replies.OrderBy(y => y.PostedDate).Last().PostedDate 
                                                    : x.PostedDate).ToList();
List topics=board.topics.OrderByDescending(x=>x.repress.Any()
?x.repress.OrderBy(y=>y.PostedDate).Last().PostedDate
:x.postedate).ToList();
主题
对象作为视图模型对象的一部分传递给视图。该视图循环浏览
Model.Topics
,并显示主题列表。问题是,我不想在视图中进行时区修改,因为我认为这对视图来说责任太大了。有没有办法在LINQ查询中修改主题日期


提前谢谢

您可以获得时区列表
System.TimeZoneInfo

var timeZones = System.TimeZoneInfo.GetSystemTimeZones();

foreach ( var timeZone in timeZones )
{
  Console.WriteLine( "{0} - {1}", timeZone.Id,  timeZone.DisplayName );
}
您可以使用该列表填充用户配置文件页面上的下拉列表。所选值应与每个用户的配置文件数据一起存储

然后可以使用TimeZoneInfo.ConvertTime将任何日期时间转换为用户时区。假设你知道它是在哪个时区创建的

var now = DateTime.Now;
Console.WriteLine( now );
Console.WriteLine( System.TimeZoneInfo.ConvertTime( now, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById( "China Standard Time" ) ) );
至于在何处进行转换,您可以在控制器中而不是在视图中进行转换。最好是在进行转换的主题顶部创建一个视图模型

另一方面,创建一个助手函数来进行转换,该转换可以从视图中访问,并适当地使用它。就我个人而言,我不会害怕这样做

如果您厌倦了在数据库中进行转换,那么将严重限制对从数据库返回的数据执行对象缓存的能力


也可以考虑将所有日期转换为UTC时间,然后再将它们插入数据库中。这将使排序正确(关于夏令时),并限制托管环境在时区间移动或跨时区托管时可能出现的任何问题。

我知道这是一个已回答的问题。我加上我的几分钱也是为了将来参考。这也是另一种方法

我的完整解决方案如下。所有时间都作为UTC存储在数据库中。您可以选择另一个时区作为默认时区。但是计算会变得复杂。若你们决定把你们的东道主搬到另一个国家,这将是一个问题

数据库 首先,需要将用户选择的时区存储在保存用户信息的某个表中。基本上,我们将存储TimeZoneInfo.Id(字符串值)。这很容易再次创建TimeZoneInfo类

接下来,创建一个用户定义的函数并将return设置为datetime。这将在需要服务器时间的整个数据库中使用。代码如图所示

Create FUNCTION [dbo].[fnGetDateTime] ()

RETURNS datetime

AS

BEGIN

RETURN GETUTCDATE()


END
这将返回UTC时间。我们可以在数据库中的任何地方直接使用GETUTCDATE()方法。但使用UDF可以在维护方面提供灵活性

代码 我们可以在日期时间类中使用方法可扩展性。由于此解决方案基于asp.net,因此计算时间很困难。问题是,有三方参与。数据库服务器、Web服务器和用户。每个都可以在不同的时区。但我们需要完全依赖用户选择的时区和UTC时间

我用两种额外的方法验证了DateTime结构

Namespace Extensions
    Public Module ModDateTimeExtensions

        <System.Runtime.CompilerServices.Extension()> _
        Public Function GetUserTimeFromUTC(ByVal dtUtcTime As DateTime, ByVal id As String) As DateTime
            Return TimeZoneInfo.ConvertTimeFromUtc(dtUtcTime, TimeZoneInfo.FindSystemTimeZoneById(id))
        End Function

        <System.Runtime.CompilerServices.Extension()> _
        Public Function SetUserTimeToUTC(ByVal dtUserTime As DateTime, ByVal id As String) As DateTime
            Return TimeZoneInfo.ConvertTime(dtUserTime, TimeZoneInfo.FindSystemTimeZoneById(id), TimeZoneInfo.Utc)
        End Function

    End Module
End Namespace
如果要将用户时间节省到UTC,请致电

Dim dt as DateTime = GetUserSelectedTimeFromUI()

dt = dt.SetUserTimeToUTC("Pacific Standard Time")
这提供了以下灵活性,

如果需要在现有系统中实现,则编码更少,更改更少

易于维护

将来,如果您想实现用户可选择的日期时间格式,可以按照相同的方式进行小改动

Dim dt as DateTime = GetUserSelectedTimeFromUI()

dt = dt.SetUserTimeToUTC("Pacific Standard Time")