C#将日期时间分配给数据行时丢失时区信息
正如标题所述,在我使用时区UTC分配DateTime对象后,当分配给DataRow时,它将丢失其时区信息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
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
函数只会执行任何操作。