Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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# 当时间具有时区信息时,将XML读入Datatable会给出错误的DateTime_C#_Xml_Datetime_Timezone - Fatal编程技术网

C# 当时间具有时区信息时,将XML读入Datatable会给出错误的DateTime

C# 当时间具有时区信息时,将XML读入Datatable会给出错误的DateTime,c#,xml,datetime,timezone,C#,Xml,Datetime,Timezone,因此,我的客户机运行一些代码,将它们的当前时间写入xml文件,然后我想将其读回数据表,但我得到的时间信息不正确 例如,他们的当前时间是09:31他们的时区是UTC+1:00 我的代码是: var ds = new DataSet("MyDataSet"); var dt = ds.Tables.Add("MyDataTable"); dt.Columns.Add("MyDateTime", typeof(DateTime)); var startingDateTime = DateTime.N

因此,我的客户机运行一些代码,将它们的当前时间写入xml文件,然后我想将其读回数据表,但我得到的时间信息不正确

例如,他们的当前时间是09:31他们的时区是UTC+1:00

我的代码是:

var ds = new DataSet("MyDataSet");
var dt = ds.Tables.Add("MyDataTable");
dt.Columns.Add("MyDateTime", typeof(DateTime));

var startingDateTime = DateTime.Now;
dt.Rows.Add(startingDateTime);
String xmlDT = String.Empty;

using (MemoryStream memoryStream = new MemoryStream())
{
    dt.WriteXml(memoryStream,XmlWriteMode.WriteSchema);
    xmlDT = Encoding.UTF8.GetString(memoryStream.ToArray());
}
string myFile = @"C:\Users\me\Documents\test1.txt"
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlDT);
doc.Save(myFile);
myFile现在包含:

<NewDataSet>
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="MyDataTable" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="MyDataTable">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="MyDateTime" type="xs:dateTime" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <MyDataTable>
    <MyDateTime>2015-02-12T09:31:37.4250365+01:00</MyDateTime>
  </MyDataTable>
</NewDataSet>

我的datatable现在包含一行datetime为08:30,但这是不正确的,我希望它存储客户端时间。如果更改客户端或服务器代码,我将如何执行此操作?

我建议只需将
MyDateTime
列的类型更改为
string

2015-02-12T09:31:37.4250365+01:00这样的字符串可以很容易地解析为a,这使得处理不同时区的日期更容易

// note I changed +01:00 to +05:00 since I'm in de-DE (+01:00)
// to illustrate the difference
var offset = DateTimeOffset.Parse("2015-02-12T09:31:37.4250365+05:00");

//prints '12.02.2015 09:31:37' (the "original" date)
Console.WriteLine(offset.DateTime);      

//prints '12.02.2015 05:31:37 +01:00' (converted to local time)
Console.WriteLine(offset.ToLocalTime()); 

因此,客户端可以添加以下行:

dt.Columns[0].DateTimeMode = DataSetDateTime.Unspecified;
或者作为更通用的方法:

public static void RemoveTimezoneForDataSet(DataSet ds)
{
    foreach (DataTable dt in ds.Tables)
    {
        foreach (DataColumn dc in dt.Columns)
        {

            if (dc.DataType == typeof(DateTime))
            {
                dc.DateTimeMode = DataSetDateTime.Unspecified;
            }
        }
    }
}
这将XML另存为:

<NewDataSet>
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="MyDataTable" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="MyDataTable">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="MyDateTime" msdata:DateTimeMode="Unspecified" type="xs:dateTime" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <MyDataTable>
    <MyDateTime>2015-02-12T09:13:39.8180356</MyDateTime>
  </MyDataTable>
</NewDataSet>

2015-02-12T09:13:39.8180356

因此,时间在服务器上被正确序列化

此方法的唯一问题是,我稍后将datatable馈送到Sql数据库中,并且我希望将datetime馈送到中,而不是字符串中。尽管我认为这是一个很好的客户机解决方案,如果我要在服务器上重建datatable,您不必将字符串保存在数据库中。SQL Server有一个名为
datetimeoffset
的类型,它具有时区感知功能。我只是想指出,您可能不想在
DataTable
中使用
DateTime
,因为它会删除xml中可用的时区信息。@user1如果您能解释一下您想要实现的目标,那会有所帮助。在数据库中存储日期时,也可以严格使用UTC时间(例如使用
DateTime.ToUniversalTime()
);但似乎你只是想删除时区信息?这似乎是个坏主意。想想夏时制吧!但现在你只是失去了日期的时区。在一个必须处理多个不同时区的应用程序中,没有时区信息的日期是没有意义的。@sloth很好的一点,这个方法在客户端上的一个缩回意味着您丢失了额外的信息
<NewDataSet>
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="MyDataTable" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="MyDataTable">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="MyDateTime" msdata:DateTimeMode="Unspecified" type="xs:dateTime" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <MyDataTable>
    <MyDateTime>2015-02-12T09:13:39.8180356</MyDateTime>
  </MyDataTable>
</NewDataSet>