Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当存储为UTC时,如何全局序列化和反序列化日期与日期时间?_C#_Sql Server_Datetime_Asp.net Web Api_Json.net - Fatal编程技术网

C# 当存储为UTC时,如何全局序列化和反序列化日期与日期时间?

C# 当存储为UTC时,如何全局序列化和反序列化日期与日期时间?,c#,sql-server,datetime,asp.net-web-api,json.net,C#,Sql Server,Datetime,Asp.net Web Api,Json.net,在我的SQL Server数据库中,我将所有DateTime值存储为UTC。不过,在某些情况下,我并不关心时间,比如某个随机时区的用户使用日期选择器选择日期。在这些情况下,只存储为DatevsDateTime似乎更有意义 当从数据库中获取日期并通过Web API将其发送到Angular应用程序时,我希望确保我所有的DateTime值的格式能够使Angular知道它们是UTC日期并显示为本地时间,因此我将此添加到Web API中,以便在末尾添加“Z”: // Set all dates to UT

在我的SQL Server数据库中,我将所有
DateTime
值存储为UTC。不过,在某些情况下,我并不关心时间,比如某个随机时区的用户使用日期选择器选择日期。在这些情况下,只存储为
Date
vs
DateTime
似乎更有意义

当从数据库中获取日期并通过Web API将其发送到Angular应用程序时,我希望确保我所有的
DateTime
值的格式能够使Angular知道它们是UTC日期并显示为本地时间,因此我将此添加到Web API中,以便在末尾添加“Z”:

// Set all dates to UTC
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter
{
    DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
});
这是可行的,但问题是,这种转换也应用于我的
日期
值。当一个日期从数据库拉入C#时,它们在
DateTime
变量中,因为C#没有
date
变量,所以它们的时间是午夜。因此,如果CST中的用户选择的日期是2018年11月24日,当它往返于数据库时,它就变成了2018年11月23日(下午6:00被截断)

如何防止这种行为?一些想法可以是:

  • 是否有条件地应用IsoDateTimeConverter?
    • 我认为这在全球范围内是不可能的,因为我无法判断它是存储在C#DateTime变量中的
      Date
      还是
      DateTime
  • 将SQL Server中的数据类型更改为
    DateTime
    • 我认为这也行不通,因为即使我根据数据的来源存储时间,对于其他时区的用户来说,它是否仍然是错误的

  • 使用@John的建议,我创建了一个自定义IsoDateTimeConverter:

    public class DateConverter : IsoDateTimeConverter
    {
        public DateConverter()
        {
            DateTimeFormat = "MM-dd-yyyy";
        }
    }
    
    并手动将其应用于每个
    Date
    值,该值覆盖了我添加到Web API配置中的全局转换器

    [JsonConverter(typeof(DateConverter))]
    public System.DateTime StartDate { get; set; }
    
    我仍然希望有一种全局方法来处理这个问题,而不是将属性应用于每个
    Date
    属性,但这至少让我松了一口气


    向有棱角的用户发出警告。我最初尝试使用格式“yyyy-MM-dd”,但它必须将其解释为UTC,因为我在向用户显示日期时遇到了相同的问题。但将其改为“MM dd yyyy”还是有效的。请参见

    顺便说一句,您可以对ISO8601格式的日期使用DateTimeFormat“o”。当然,这对你的问题没有多大帮助。因为你使用的是JSON.NET,你可以在这些日期字段上使用[JsonConverter]属性。“我很想看看是否有更好的解决办法。”约翰,我考虑过这样做。如果可能的话,我更愿意在全球范围内处理。如果我真的这样做了,你知道该属性是否会覆盖全局IsoDateTimeConverter,以便我仍然可以对所有其他DateTime值使用全局转换器吗?我认为应该这样做,但不要让我这么认为。首先,你似乎对它感到困惑。第一个是特殊时区,第二个是日期/时间/日期时间和期间的字符串表示的标准规范。其次,如果您使用的是Sql Server,我认为您已经找到了正确的解决方案。如果您的类对
    Date
    DateTime
    使用了不同的数据类型来镜像数据库,那么您可以在全局配置中使用针对该类型的自定义转换器(与DateTime的其他转换器一起使用),并且您不需要这些属性。但是,由于它们使用相同的数据类型,您仍然需要某种属性来区分它们,以便能够全局应用转换器(例如,使用自定义协定解析程序)。因此,您不妨使用
    [JsonConverter]
    属性直接应用转换器并跳过解析器。