C# 使用WCF服务和DataTable序列化/反序列化时停止DateTime的自动本地化

C# 使用WCF服务和DataTable序列化/反序列化时停止DateTime的自动本地化,c#,wcf,datetime,serialization,C#,Wcf,Datetime,Serialization,我搞不懂这件事,快把我逼疯了。我无法理解为什么数据类型对象会这样做。我觉得指定的处理时区的类型就足够了。不管怎样,这是我的设置。我有一个WCF服务,它向我的应用程序提供一个序列化数据表。数据通过web界面输入。如果我将2014年12月12日上午11:00输入数据库,它将通过web服务严格地将数据表中的2014年12月12日下午12:00返回到我的应用程序 我怎么才能阻止这一切 事件链: 登录到web界面,选择立即执行任务(传递DateTime.now)或稍后执行任务(解析用户选择的日期时间常数的

我搞不懂这件事,快把我逼疯了。我无法理解为什么数据类型对象会这样做。我觉得指定的处理时区的类型就足够了。不管怎样,这是我的设置。我有一个WCF服务,它向我的应用程序提供一个序列化数据表。数据通过web界面输入。如果我将2014年12月12日上午11:00输入数据库,它将通过web服务严格地将数据表中的2014年12月12日下午12:00返回到我的应用程序

我怎么才能阻止这一切

事件链:

  • 登录到web界面,选择立即执行任务(传递DateTime.now)或稍后执行任务(解析用户选择的日期时间常数的字符串表示形式)。我将时区存储在一个单独的列中。 注意:DateTime.Now将不会由序列化程序自动本地化,另一个将自动本地化
  • 任务设置正确。所有日期都正确反映在数据库中。目前还没有差异
  • 任务将在设置的正确时间执行。因为我在处理时区的差异,所以这些任务设置为在中执行。这是工作顺利。任务在应该执行的时候执行
  • 看看电话。时间不对。我中断了该点,并且来自已序列化和反序列化的datatable中的web服务的数据不正确。休息一小时(从芝加哥时间到美国东部时间)
  • 我在不同的地方尝试过改变这种方式,但没有任何效果

    我希望我输入到数据库中的内容与显示的内容完全一致。我通过简单的算法处理数据库逻辑中的时区转换。不需要这种自动化


    对于这样一个老问题,我厌倦了在成堆的工作环境中挖掘,这些工作都没有,或者有足够好的决议来解释该做什么以及如何处理这个问题。

    我得到了它,尽管它做了很多调整。这也是我的特定设置,可能不适用于所有人

    我的设置: 日期时间从数据库所在时区的web界面传递到数据库。在相同时区中运行的Windows服务根据show after字段循环并拉出任务。然后从任何时区的手机应用程序中提取该数据,并以多长时间前(如1分钟前、2小时前等)的形式显示值。手机应用程序是唯一与WCF服务接口的应用程序。由于Windows服务驻留在同一台服务器上,因此不需要任何中间人

    首先,在网站上输入这些“任务”时,日期和时间通过以下方式获得

    Double selectedTimezone = 0D;
    Double offsetTimezone = 0D;
    
    TimeZoneInfo timezoneInfo = TimeZoneInfo.Local;
    
    selectedTimezone = Double.Parse(DDL_EndTimezone.SelectedValue.ToString());
    
    /* Obtain the timezone offset for server to user. 
       For me this is -1: -6 (CST) to -5 (EST) */
    
    offsetTimezone = (timezoneInfo.BaseUtcOffset.TotalHours - selectedTimezone);
    
    /* Parse the date time from the selected user 
       inputs. */
    
    if (!chkSendMessageNow.Checked)
        start = DateTime.Parse(txtBeginDate.Text + " " + cmdBeginHour.SelectedValue.ToString() + ":" + cmdBeginMinute.SelectedValue.ToString() + ":" + "00");
    else
        start = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy") + " " + DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + "00");
    end = DateTime.Parse(txtEndDate.Text + " " + DDL_EndHour.SelectedValue.ToString() + ":" + DDL_EndMin.SelectedValue.ToString() + ":" + "00");
    
    /* Ensure these are "local" kind. I quote because 
       this is local time for user, not where the 
       site is hosted. */
    
    start = DateTime.SpecifyKind(start, DateTimeKind.Local);
    end = DateTime.SpecifyKind(end, DateTimeKind.Local);
    
    /* Convert the start and end to UTC from 
       the timezone of the user with the 
       adjusted server to user timezone 
       offset. */
    
    start = start.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
    end = end.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
    
    /* Specify this is UTC. */
    
    start = DateTime.SpecifyKind(start, DateTimeKind.Utc);
    end = DateTime.SpecifyKind(end, DateTimeKind.Utc);
    
    DateTime showAfter = DateTime.MinValue;
    
    showAfter = Convert.ToDateTime(_dataTable.Rows[position]["ShowAfter"]);
    showAfter = DateTime.SpecifyKind(showAfter, DateTimeKind.Utc);
    showAfter = showAfter.ToLocalTime();
    
    现在这些都保存到数据库中

    在我的WCF服务的服务器上,我拉取DataTable,但在返回要序列化的输出之前调整DateTime列,如下所示。 此步骤可能不是必需的,并且是以前尝试的剩余步骤。但我没有搞乱它,因为它起作用了

    Int32 upperBound = (output.Rows.Count - 1);
    
    DateTime showAfter = DateTime.MinValue;
    DateTime showBefore = DateTime.MinValue;
    
    for (Int32 i = upperBound; (i >= 0); i--)
    {
        showAfter = (DateTime)output.Rows[i]["ShowAfter"];
        showBefore = (DateTime)output.Rows[i]["ShowBefore"];
    
        showAfter = DateTime.SpecifyKind(showAfter, DateTimeKind.Utc);
        showBefore = DateTime.SpecifyKind(showBefore, DateTimeKind.Utc);
    
        output.Rows[i]["ShowAfter"] = showAfter;
        output.Rows[i]["ShowBefore"] = showBefore;
    }
    
    最后在应用程序中显示反序列化时的正确本地化时间。我做以下几件事

    Double selectedTimezone = 0D;
    Double offsetTimezone = 0D;
    
    TimeZoneInfo timezoneInfo = TimeZoneInfo.Local;
    
    selectedTimezone = Double.Parse(DDL_EndTimezone.SelectedValue.ToString());
    
    /* Obtain the timezone offset for server to user. 
       For me this is -1: -6 (CST) to -5 (EST) */
    
    offsetTimezone = (timezoneInfo.BaseUtcOffset.TotalHours - selectedTimezone);
    
    /* Parse the date time from the selected user 
       inputs. */
    
    if (!chkSendMessageNow.Checked)
        start = DateTime.Parse(txtBeginDate.Text + " " + cmdBeginHour.SelectedValue.ToString() + ":" + cmdBeginMinute.SelectedValue.ToString() + ":" + "00");
    else
        start = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy") + " " + DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + "00");
    end = DateTime.Parse(txtEndDate.Text + " " + DDL_EndHour.SelectedValue.ToString() + ":" + DDL_EndMin.SelectedValue.ToString() + ":" + "00");
    
    /* Ensure these are "local" kind. I quote because 
       this is local time for user, not where the 
       site is hosted. */
    
    start = DateTime.SpecifyKind(start, DateTimeKind.Local);
    end = DateTime.SpecifyKind(end, DateTimeKind.Local);
    
    /* Convert the start and end to UTC from 
       the timezone of the user with the 
       adjusted server to user timezone 
       offset. */
    
    start = start.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
    end = end.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
    
    /* Specify this is UTC. */
    
    start = DateTime.SpecifyKind(start, DateTimeKind.Utc);
    end = DateTime.SpecifyKind(end, DateTimeKind.Utc);
    
    DateTime showAfter = DateTime.MinValue;
    
    showAfter = Convert.ToDateTime(_dataTable.Rows[position]["ShowAfter"]);
    showAfter = DateTime.SpecifyKind(showAfter, DateTimeKind.Utc);
    showAfter = showAfter.ToLocalTime();
    

    我尝试在不同的地方更改该类型,但没有任何效果
    我尝试在将值提交到数据库之前设置DateTime.kind。然后我试着在应用程序上显示消息设置显示的时间跨度。在我看来,我必须在两者之间的某个地方设置一种。对我来说,这意味着返回数据表的WCF Web服务。我没有尝试遍历表并设置列种类,然后返回修改后的表。就个人而言,如果这能解决问题,这似乎是一项昂贵的工作。也许我弄错了,应该试一试。在数据库之前进行设置肯定不会起任何作用;该字段未保存。问题是在您从数据库中读取后,它将具有
    DateTime.Kind
    等于
    Unspecified
    ,并且您希望它是
    Utc
    (或者按照惯例)。所以,是的,你应该尝试一下(不会很贵)@wal一些关于这方面的东西<代码>Int32上限=(output.Rows.Count-1);对于(Int32 i=上限;(i>=0);i--){DateTime showAfter=(DateTime)output.Rows[i][“showAfter”];DateTime showBefore=(DateTime)output.Rows[i][“showBefore”];showAfter=DateTime.SpecifyKind(showAfter,DateTimeKind.Utc);showBefore=DateTime.SpecifyKind(showBefore,DateTimeKind.Utc);output.Rows[i][“showAfter”]=showAfter;output.Rows[i][“ShowBefore”]=ShowBefore;}不起作用:(在手机上显示时,时间仍然提前了一个小时。数据库显示上午9:20,手机显示上午10:20。数据库位于德克萨斯州(CMT),而我目前在纽约东部时间,因此差异是有意义的。