2013-07-12 83 views
3

正如标题所示,在分配具有时区UTC的DateTime对象后,分配给DataRow时会丢失其TimeZone信息。将DateTime分配给DataRow时,C#TimeZone信息丢失

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后,它说Kind = Unspecified。

这是DataRow中的错误还是我在这里做错了?

+4

似乎它已经回答[http://stackoverflow.com/questions/3990809/how-to-persist-datetime-kind-while-storing-a-datetime-object -into-a-data-table] – Rwiti

+0

重要吗?为了在数据库中存储时间,存储为UTC是唯一有意义的格式。 – spender

+0

dup文件有答案,但也要注意'Kind'并不能真正保留时区信息。这只是一个规则,说明在与时区功能交互时如何处理该值。无论如何,在保存数据时通常不会持续存在。你可以把UTC看作是一个时区,但是Local或Unspecified类型有点不同。如果持久性是你所追求的,你可能想看看'DateTimeOffset'。即使您的偏移量为零,它至少会以这种方式坚持而不会丢失。 –

回答

0

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

例如,在SQL Server上,datetime类型没有时区信息。因此,DateTime类型的任何C#值都只存储其值。这与Linq-to-SQL和Entity Framework的工作方式类似。

我的解决方法通常是为所有持久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(); 
} 
+0

有趣,但我不确定这些是否合理。对于'InputTime',通常来自输入的日期是'Unspecified',因为它们是从UI中的字符串进行分析的。对于'OutputTime'来说,它肯定没有意义,因为你将时间标记为UTC,然后再次尝试将其转换为UTC,这将是无操作的。我不确定这些如何能帮助OP的问题。但谢谢你的尝试。 –

+0

@MattJohnson - UI的日期应该在持久层之前转换为DateTimeKind.Local。这就是为什么'InputTime'引发一个异常:日期需要在持续之前有一个已知的'Kind'。 'OutputTime'方法的目的是直接从持久层获取日期,在几乎所有情况下(但可能不是在单元测试场景中)都有一个未指定的Kind类。它应用UTC类型并以UTC为单位返回该值(如果'time'参数恰好具有指定的'Kind',则返回该类型。 – ken

+0

不尝试启动参数,但我不同意您的意见。几乎所有的情况下,'DateTimeKind.Local'都是邪恶的。阅读[我的博客文章](http://codeofmatt.com/2013/04/25/the-case-against-datetime-now/),如果你不相信我 - 请看[Jon Skeet对此有何想法](http://noda-time.blogspot.com/2011/08/what-wrong-with-datetime-anyway.html)。它有一个未成年人*纯桌面*应用程序的便利,但除此之外,它只是阻碍了事情的发展,并且造成了一些混乱的事情 –