为啥将 1 传递给日期时返回“31-12-1899”?

Posted

技术标签:

【中文标题】为啥将 1 传递给日期时返回“31-12-1899”?【英文标题】:Why does the date returns "31-12-1899" when 1 is passed to it?为什么将 1 传递给日期时返回“31-12-1899”? 【发布时间】:2016-07-22 13:37:15 【问题描述】:

我使用的是 Windows 10 OS excel 13,所以在下面的代码中 1 应该返回 1/1/1900 对吗?下面不是为什么。

在this 问题上,OP 通过了2016 并得到了与我相同的结果,所以如果出现错误,为什么当我通过2016 时得到与 OP 相同的结果?

Sub ndat()

Dim dt As Date
dt = 2016
Debug.Print "dt is " & dt

End Sub

【问题讨论】:

因为所有 MS Office 应用程序中的基准日期(日期零)都是 12-30-1899,并且在该日期上加 1 会导致 12-31-1899。 (您可以通过在 Excel 单元格中输入 0 并将其格式化为日期来自己验证这一点。) @KenWhite 那么为什么 MacroMan 在 cmets 中有 1/1/1900 here。你也可以在你的系统上做?CDate(1) 告诉我你得到了什么吗? @KenWhite 关于纪元日期是正确的 - 你可以阅读 why here @Comintern 我知道“Lotus 123 错误” - 但为什么会有difference between worksheet and VBE? @MacroMan - 打败我。我只是指出 12-30-1899 是纪元日期。 【参考方案1】:

VBA 中的整数和日期映射不同于工作表中的映射。例如:

Sub marine()
    Dim i As Integer, d As Date
    Dim mgs As String

    msg = ""
    For i = -10 To 10
        d = CDate(i)
        msg = msg & i & vbTab & Format(d, "mm/dd/yyyy") & vbCrLf
    Next i

    MsgBox msg
End Sub

生产:

请注意,您可以获取 1/1/1900

之前的日期

编辑#1:

这可能有助于理解差异。我在 A 列中放了一些整数。

B1中,我输入=A1并复制下来。我将列 B 格式化为以日期格式显示。

我使用这个 UDF():

Public Function VBA_Date(i As Long) As String
    VBA_Date = Format(CDate(i), "mm/dd/yyyy")
End Function

填充列C

注意第 19 行和第 20 行之间的过渡

【讨论】:

不是我的问题,但你知道为什么零日期不同吗?我认为这才是这个三明治里真正的肉。 @MacroMan 这不仅仅是零日期! 我的措辞不好 - 我的意思是为什么工作表和 VBA 之间的整数到日期映射不同? @MacroMan 因为 VBA 中的映射缺少特定的错误.....我会更新我的帖子...... .... 因此假设存在差异是否公平,因为在 worksheet 中由于 Lotus 1-2-3 错误而需要这样做,而在VBA 从来没有要求这种向后兼容性 - 因此理论上 VBA 是并且一直是正确的?【参考方案2】:

这只是工作表本身。或者是正确的:工作表功能!

快速测试:

?cdate(1)
1899-12-31 
?format(1,"YYYY-MM-DD")
1899-12-31
?worksheetfunction.Text(1,"YYYY-MM-DD")
1900-01-01

但是选择今天的日期并没有显示出这种差距:

?clng(now)
 42463 
?worksheetfunction.Text(now,"0")
42463

这表明 1 到 42463 之间的某个位置是一个间隙(快速的莲花检查显示它:

?cdate(60) & " --- " & cdate(61)
1900-02-28 --- 1900-03-01
?format(60,"YYYY-MM-DD") & " --- " & format(61,"YYYY-MM-DD")
1900-02-28 --- 1900-03-01
?worksheetfunction.Text(60,"YYYY-MM-DD") & " --- " & worksheetfunction.Text(61,"YYYY-MM-DD")
1900-02-29 --- 1900-03-01

最后一次测试再次展示它:

?format("1900-02-28","0") & " --- " & format("1900-03-01","0")
60 --- 61
?worksheetfunction.Text("1900-02-28","0") & " --- " & worksheetfunction.Text("1900-03-01","0")
59 --- 61

从 61 开始,现在只是数字不同。但是 Lotus-Bug 添加了 1900-02-29 来表示“兼容性”。

另外:这是 excel 的“功能”,与基本、vbscript、vba 无关......所有其他程序都以正确的方式工作,如果VBA 不会。因此,为了“兼容性”,Excel 中的 VBA 只是以正确的方式进行;)

【讨论】:

以上是关于为啥将 1 传递给日期时返回“31-12-1899”?的主要内容,如果未能解决你的问题,请参考以下文章

查询 SQL 时,传递给查询的时间比我设置的时间少 2 小时。为啥?

为啥没有将详细的错误消息传递给 HttpClient?

为啥只传递 1 个参数时 argc 返回 2? [复制]

为啥通过 ParamArray 将数组元素传递给函数时,varpointer 会到达函数中?

C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?

为啥将 C-Array 传递给函数时 sizeof() 值错误? [复制]