存储DateTime(UTC)与存储DateTimeOffset

时间:2011-01-17 16:48:24

标签: sql sql-server tsql sql-server-2008 datetimeoffset

我通常有一个“拦截器”,它在从/向数据库读/写之前进行DateTime转换(从UTC到本地时间,从本地时间到UTC),所以我可以使用DateTime.Now(派生)并且整个系统都没有担心时区。

关于序列化和在计算机之间移动数据,没有必要打扰,因为日期时间始终是UTC。

我应该继续以UTC格式存储我的日期(SQL 2008 - datetime),还是应该使用DateTimeOffset存储它(SQL 2008 - datetimeoffset)?

UTC数据库中的日期(日期时间类型)已经工作并且已知很长时间了,为什么要更改它?有什么好处?

我已经查看了像this one这样的文章,但我并不是100%相信。有什么想法吗?

3 个答案:

答案 0 :(得分:113)

有一个巨大的区别,你不能单独使用UTC。

  • 如果你有这样的场景

    • 一台服务器多个客户(所有地理位置在不同的时区
    • 客户使用日期时间信息创建一些数据
    • 客户端将其全部存储在中央服务器上
  • 然后:

    • datetimeoffset将UTC时间和ALSO偏移存储到客户端的本地时间
    • 所有客户都知道所有数据的UTC时间以及信息来源地点的当地时间
  • 可是:

    • UTC日期时间仅存储UTC日期时间,因此您没有关于数据来源的客户端位置的本地时间信息
    • 其他客户不知道该地点的当地时间,其中日期时间信息来自
    • 其他客户只能从数据库计算本地时间(使用UTC时间),而不是客户端的本地时间,数据源自

简单的例子是机票预订系统......机票应该包含2次:    - “起飞”时间(在“从”城市的时区)    - “着陆”时间(在“目的地”城市的时区)

答案 1 :(得分:20)

在所有历史时间(即记录事件发生)使用UTC是绝对正确的。始终可以从UTC到当地时间,但并不总是相反。

何时使用当地时间?回答这个问题:

  

如果政府突然决定改变夏令时,你会喜欢这个吗?    数据随之改变?

如果答案为“是”,则仅存储当地时间。显然,这仅适用于未来的日期,通常仅适用于以某种方式影响人们的日期。

为什么要存储时区/偏移?

首先,如果您想记录执行操作的用户的偏移量,您可能最好这样做,即在登录时记录该用户的位置和时区。

其次,如果你想转换为显示,你需要有一个包含该时区所有本地时间偏移转换的表,只需知道当前的偏移是不够的,因为如果你显示的是六个月前的日期/时间偏移量会有所不同。

答案 2 :(得分:18)

DATETIMEOFFSET使您能够在一个字段中存储本地时间和UTC时间。

这样可以在本地或UTC时间内进行非常简单有效的报告,而无需以任何方式处理数据以进行显示。

这是两个最常见的要求 - 本地报告的本地时间和组报告的UTC时间。

本地时间存储在DATETIMEOFFSET的DATETIME部分中,而来自UTC的OFFSET存储在OFFSET部分中,因此转换很简单,因为它不需要知道数据来自的时区,所有都可以完成在数据库级别。

如果您不需要时间长达毫秒,例如只需几分钟或几秒钟,就可以使用DATETIMEOFFSET(0)。然后,DATETIMEOFFSET字段只需要8个字节的存储空间 - 与DATETIME相同。

因此,使用DATETIMEOFFSET而不是UTC DATETIME可以为报告提供更大的灵活性,效率和简便性。