首页 目录页 热情软件屋 问专家

李海文选

Visual Basic 也存在2000年问题

李海

本文发表在《计算机世界》97年10月13日39期

         Visual Basic 以 其 灵 活 易 学 的 特 点 成 为 目 前Windows 开 发 的 主 要 工 具, 可 你 想 到 没 有, 当 世 纪 钟 声 敲 响 之 时, 你 的VB 程 序 会 怎 样 呢 ?

         笔 者 研 究 的 结 果 说 明Visual Basic 的2000 年 问 题 比 较 复 杂, 因 版 本 而 异。

         为 了 考 察Visual Basic 的2000 年 问 题, 我 编 写 了 如 下 这 段 程 序:


Dim sDate As String

    Dim vDate As Variant



    sDate = "Jan 1 01"

    vDate = CVDate(sDate)



    Debug.Print "Now = " & Now

    Debug.Print "sDate = " & Format$(sDate, "dd/mm/yyyy")

    Debug.Print "vDate = " & Format$(vDate, "dd/mm/yyyy")

把 这 段 程 序 在 每 个 版 本 的Visual Basic 运 行 两 次, 第 一 次 运 行 系 统 时 间 采 用 本 世 纪 的 时 间1997 年8 月9 日, 另 一 次 使 用 下 世 纪 的 时 间2000 年8 月9 日。 完 成 整 个 测 试 之 后, 我 得 出 下 面 的 结 果。

         在Visual Basic 3.0 中, 两 次 的 结 果 如 下:


Now = 97/08/09 3:06:48 PM

sDate = 01/01/1901

vDate = 01/01/1901



Now = 2000/08/09 3:08:11 PM

sDate = 01/01/1901

vDate = 01/01/1901

从 结 果 中 我 们 可 以 看 出, 由 于Visual Basic 3.0 发 行 得 比 较 早, 当 时2000 年 问 题 还 没 有 引 起 人 们 的 注 意, 所 以Visual Basic 3.0 把 任 何 年 份 都 看 成 本 世 纪 的。 也 就 是 说, 可 能 会 出 现 这 样 的 情 况: 你 的 程 序 在 下 世 纪 会 突 然 使 时 光 倒 流100 年。 在 测 试 中, 我 还 发 现Format 函 数 和Year 函 数 返 回 的 结 果 是 一 样 的, 这 说 明 在Visual Basic3.0 中 只 存 在 一 种 计 算 世 纪 的 方 法。 Visual Basic 4.0 中 的 情 况 比3.0 版 复 杂 多 了。 首 先 看 看16 位 版 本。 下 面 是 测 试 的 结 果:

Now = 97/08/09 3:06:48 PM

sDate = 01/01/1901

vDate = 01/01/1901



Now = 2000/08/09 3:08:11 PM

sDate = 01/01/2001

vDate = 01/01/2001

Visual Basic 4.0 的16 位 是 根 据 当 前 系 统 日 期 来 判 断 世 纪 的。 当 前 年 份 为1997, 得 到 的 日 期 为20 世 纪 的, 若 当 前 年 份 为2000 年, 得 到 的 日 期 为21 世 纪 的。 这 也 可 能 会 出 现 问 题, 当 你 在2000 年 处 理1999 年 的 帐 目 时,Visual Basic 会 认 为 那 是2099 年 的。

         如 果 你 使 用 的 是Visual Basic 4.0 的32 位 版 本, 你 可 能 得 到 与16 位 版 本 相 同 的 结 果, 也 可 能 不 同。 这 是 因 为Visual Basic 4.0 的32 位 版 本 的 日 期 函 数( 除DateSerial 函 数 以 外) 是 从OleAut32.dll 得 到 世 纪 数 据 的。Visual Basic 4.0 的32 位 版 本 自 身 带 的 是2.10 版 本, 它 采 用 的 方 法 同Visual Basic 4.0 的16 位 版 本 一 样。 而 在Visual Basic 4.0 发 行 后, 微 软 也 意 识 到 它 处 理 世 纪 的 方 法 不 够 合 理, 所 以 在 随 后 发 行 的2.20 版 和 此 后 的 版 本 中 采 用 了 新 的 方 法。 新 方 法 认 为 如 果 年 份 的 后 两 位 在30 至99 之 间, 则 认 为 是20 世 纪, 而 若 在00 至29 之 间, 就 认 为 是21 世 纪。 这 可 以 比 较 好 地 解 决 世 纪 末 过 渡 时 期 的 世 纪 问 题, 至 于2030 年 怎 么 办, 只 能 到 时 候 再 说 了。 微 软96 年 以 后 推 出 的 软 件 中 包 括 的OleAut32.dll 都 是 采 用 此 方 法, 这 些 软 件 包 括Internet Explorer 3.0、Windows NT 3.51 Service Pack 5、Windows NT 4.0、Windows 95 OSR 2( 俗 称Windows 96)、Office 97 和Visual Studio 97 等 等。Visual Basic 5.0 也 采 用 此 方 法。 如 果 你 在Visual Basic 4.0 的32 位 版 本 中 运 行 前 面 的 测 试 程 序 得 到 的 结 果 同16 位 版 本 相 同, 说 明 你 的OleAut32.dll 是 老 版 本, 否 则 为 新 版 本。 可 见,Visual Basic 4.0 的32 位 版 本 得 到 的 结 果 取 决 于OleAut32.dll 的 版 本。 需 要 说 明 的 是,DateSerial 函 数 不 是 从OleAut32.dll 得 到 世 纪 数 据 的, 它 在Visual Basic 的16 位 和32 位 采 用 的 方 法 是 一 样 的。 以 上 是Visual Basic 各 个 版 本 对 世 纪 问 题 的 处 理 方 法。 如 果 你 的 程 序 不 会 因 此 发 生 问 题, 可 以 照 常 调 用 各 日 期 函 数。 但 如 果 会 因 此 出 问 题, 我 建 议 采 用 自 定 义 函 数 来 确 定 世 纪。 比 如, 我 有 一 个 程 序 认 为80 年 至99 年 的 日 期 都 是 本 世 纪, 而00 年 至79 年 为 下 世 纪。 可 以 编 写 如 下 的 程 序 来 返 回 四 位 年 份。


Sub MyYear( vDate As Variant) As String

	Dim s As String



	If Format$( vDate, "yy") < "80" Then

		s = "20"

	Else 

		s = "19"

	End If

	MyYear = s + Format$( vDate, "yy")

End Sub

现 在, 你 应 该 逐 个 审 核 你 的 程 序, 不 要 让 它 们 在2000 年 元 旦 的 节 日 里 给 你 找 麻 烦。

回到《李海文选》目录

如果您有任何建议,请给我发电子邮件:
版权所有 李海,热情软件屋 1997-2006


WU Banner from WebUnion Chinese Network