C#将日期时间分配给数据行时丢失时区信息

C#将日期时间分配给数据行时丢失时区信息,c#,timezone,datarow,C#,Timezone,Datarow,正如标题所述,在我使用时区UTC分配DateTime对象后,当分配给DataRow时,它将丢失其时区信息 static void Main(string[] args) { DateTime universalTime = DateTime.UtcNow; DataTable table = new DataTable(); table.Columns.Add("Time", typeof(DateTime)); DataRow row = tabl

正如标题所述,在我使用时区UTC分配DateTime对象后,当分配给DataRow时,它将丢失其时区信息

static void Main(string[] args)
  {
     DateTime universalTime = DateTime.UtcNow;

     DataTable table = new DataTable();
     table.Columns.Add("Time", typeof(DateTime));
     DataRow row = table.NewRow();

     row["Time"] = universalTime;

     /* writes Kind: Utc */
     Console.WriteLine("Universal time      : " + universalTime + ", kind: " + universalTime.Kind);

     /* writes Kind: Unspecified */
     Console.WriteLine("Same time in DataRow: " + row["Time"] + ", kind: " + ((DateTime)row["Time"]).Kind);

     Console.ReadKey();
  }
分配给DataRow后,它表示种类=未指定


这是数据行中的错误还是我在这里做错了什么?

我怀疑这是因为持久层的
datetime
数据类型中没有可用的时区信息

例如,在SQL Server上,
datetime
类型没有时区信息。因此,任何类型为
DateTime
的C#值都只存储其值。这类似于LINQtoSQL和实体框架的工作方式

我的工作通常是为所有持久化的
DateTime
值确定一个时区(UTC),并在持久化之前和检索之后进行转换

大概是这样的:

public DateTime InputTime(DateTime time) {
    if (time.Kind == DateTimeKind.Unspecified) {
        throw new ArgumentException("Time values cannot be input to the data store with unspecified kind.");
    }
    return time.ToUniversalTime();
}

public DateTime OutputTime(DateTime time) {
    if (time.Kind == DateTimeKind.Unspecified) {
        time = DateTime.SpecifyKind(time, DateTimeKind.Utc);
    }
    return time.ToUniversalTime();
}

看来已经有答案了[这有关系吗?对于在数据库中存储时间,存储为UTC是唯一有意义的格式。dup帖子有答案,但也要知道,
并不能真正保存时区信息。这只是一条规则,说明在与时区函数交互时应如何处理该值。这是一个典型的调用无论如何,在保存数据时y不会持久化。您可以将
UTC
视为时区,但
Local
Unspecified
类型有点不同。如果持久化是您所追求的,您可能希望查看
DateTimeOffset
。即使偏移量为零,也至少会以这种方式持久化,并且不会丢失。有趣,但我不确定这些是否有意义。对于
InputTime
,输入的日期通常是
未指定的
,因为它们是从UI中的字符串解析而来的。对于
OutputTime
,这当然没有意义,因为您正在将时间标记为UTC,然后尝试再次将其转换为UTC,这将是一个错误不可操作。我不确定这两种方法对操作的问题有何帮助。但感谢您的尝试。@MattJohnson-UI中的日期应该在持久化层之前转换为
DateTimeKind.Local
。这就是为什么
InputTime
抛出异常的原因:在持久化之前,日期需要有一个已知的
种类de>OutputTime
方法意味着直接从持久性层获取日期,在几乎所有情况下(但可能不是在单元测试场景中),持久性层都具有未指定的
种类
。它应用UTC种类并以UTC返回该值(如果
time
参数碰巧有一个指定的
kind
,这也是返回的类型。我不想开始一个参数,但我不得不同意你的意见。在几乎所有情况下,
DateTimeKind.Local
都是邪恶的。阅读,如果你不相信我-看。它在纯桌面应用程序中有一点小的便利,但其他的是的,这个例子来自一个桌面应用程序。用户输入的日期被赋予
Local
类型,并在任何处理之前立即转换为UTC。在调用
ToUniversalTime
之前,我从不比较日期或做任何其他处理,下面就是这个例子我演示了如何保证所有持久化的日期都有有效的
类型
。实际上,这与调用
DateTimeOffset.Now.UtcDateTime
没有太大区别,但我同意传递
DateTimeOffset
的实例可能比
DateTime
更安全,这可能是我需要注意的当然,我可以理解。但是仍然存在一个缺陷,即
ToUniversalTime
如果种类已经是UTC,则不会执行任何操作,
SpecifyKind
不会执行任何转换。因此,如果
time
参数是
Local
种类,则您的
OutputTime
函数只会执行任何操作。