【问题标题】:Casting a double to a DateTime type is off by 2 days?将双精度转换为 DateTime 类型会关闭 2 天?
【发布时间】:2011-05-13 16:54:14
【问题描述】:

出于多种原因,我将日期时间值作为 sql 浮点类型(从 DateTime.OADate 转换而来)存储在数据库中,但是在某些情况下,最好从数据库中获取人类可读的日期/时间列。我发现我可以执行语句

SELECT CAST (timerecorded_utc as DATETIME) FROM tablename

它会给我我正在寻找的日期时间字符串,但它似乎正好相差 2 天。我意识到我可以修改语句(因为时间表示为双 1 天 = 1.0)为

SELECT CAST (timerecorded_utc-2.0 as DATETIME) FROM tablename

但我想知道这是否一致,在我看来,我缺少这种差异是有原因的。

【问题讨论】:

  • 在将数据保存到数据库时会丢失一些精度吗?
  • 我认为这与精度无关,因为精确到毫秒的时间是正确的。天数在小数点前计算,时间来自小数点后的值。如果它与精度相关,那么时间就会出错(至少我认为)
  • @Matthew,日期到浮点数的转换是什么样的?
  • @Matthew - 这是 SQL Server 还是 Oracle?
  • 这是 MS SQL Server,实际上是 SQL CE(如果重要的话,它们的行为相同)

标签: c# sql


【解决方案1】:

这是因为日期使用的历元不同。

SQL Server 的 DATETIME 使用 01/01/1900 00:00:00 作为纪元,您可以通过运行以下查询来查看:SELECT CAST(0 AS DATETIME)

OADate 有点奇怪,因为它的纪元可能是 30/12/1899 00:00:00 或 31/12/1899 00:00:00,具体取决于您分别相信 Visual Basic 还是 Excel 家伙.从您的两天差异来看,.NET 版本似乎与第 30 天一致。

因此,当您通过原始数字在两种类型的日期之间进行转换时,相差两天的纪元会产生两天的结果差异。

【讨论】:

  • 有人知道这种疯狂有什么方法吗?
  • 太棒了为什么我没有想到这个...如果我运行 DateTime.FromOADate(0.0) 我得到 12/30/1899 12:00:00 AM 谢谢!!!!跨度>
  • Excel也有一个“特点”——故意从 Lotus 1-2-3 继承!&mdahs,其中错误地执行了跳跃规则规则。正确的闰年规则是
  • @Lee - Joel Spolsky 在这里写了一些历史:joelonsoftware.com/items/2006/06/16.html
  • 有关此问题的更多背景信息,请参阅我关于该主题的文章:blogs.msdn.com/b/ericlippert/archive/2003/09/16/53013.aspx
【解决方案2】:

Epic Epochs... 这是我在 SQL Server 中使用内置的 TSQL 解决方案 “添加日期”函数:

Select DateAdd(DAY, cast([ENDING DATE] as decimal(10,0)), '12/30/1899')
from YourTable

在我的情况下,我通过 C# Core App 导入保存在 Excel 中的字符串并上传到 SQL Server 数据库,因此我的 [结束日期] 是一个字符串,我将其转换为没有精度的小数,因为我只需要实际日期,而不是一天中的时间。正如@GregBeech 提到的,您的基准日期可能是“1899 年 12 月 31 日”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多