大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> 程序开发 -> Delphi系列的Y2K问题

Delphi系列的Y2K问题

时间: 2021-07-31 作者:daque

delphi兴盛于今,仍旧是第六本子了。纵然各个本子有大巨细小的bug,但疵不掩暇,她仍旧博得了宏大步调员和编制程序喜好者的追和蔼保护。跟着2000年的迫近, y2k的一系列题目和百般处置计划也就随之提到议程上去。对编制程序者来说,咱们此刻关怀的中心是:delphi系列有没有y2k题目呢? ---- 谜底固然是确定的。从 delphi4 起,inprise 公司就在体例单位 sysutils. pas(dcu)中减少了twodigitcenturywindow 这一要害词。它表白从暂时年份起加到两位数的年份的数值,缺省为50(年),也即是说承诺y2k拖后50年才爆发。不妨如许举一大略的例子: ---- 暂时日子为 1999年,挪用 formatdatetime(longdateformat,'20-11-04') 为 2020年11月4日。而 formatdatetime(longdateformat,'50-11-04') 却为 1950年 11月4日 而不是 2050 年11月4日。 ---- 所以,此刻的y2k题目计划不过在篡夺功夫,而没有完全处置. 理念的回答是到了 2000年,年份的输出和表白该当是4位数,而不是两位,如许本领除牺牲纪之交的二义性。 ---- 沿着这一思绪 delphi第5中学最要害的插件 midas 3.x(多层散布式运用效劳),也是创造在这一功夫差普通之上的,它常常和 bde 的y2k 矫正日子范畴接洽在一道。须要提防的是:运转时(rtl)控件,inspire 倡导在日子多运用场所,如出身备案,到时付款凭据等工作处理当用时,可按照本人的本质须要来设定(twodigitcenturywindow) 这一初始值,最佳简直窗口建登时,及 oncreate 事变内里树立。inprise 倡导用 100年的世纪窗口(the century window)(对立2000年往日),大局部步调员都爱好如许设 twodigityearcenturywindow := currentyear - 1950。 ---- 100年的世纪窗口(the century window)应作如次证明 : ---- 设 twodigitcenturywindow := 20,那么从此刻起,功夫扶助是20年,个中80年应为往日功夫。如:暂时功夫是 1999年,formatdatetime(longdateformat,'18-11-04') 为 2018年11月4日,胜过了克日,formatdatetime(longdateformat,'20-11-04') 为 1920年11月4日。 ---- 在规范控件中,与日子输出相关的插件是 tmaskedit.及其派生的子类。tdatetimepicker 插件在没有安置最新的微软 visual dev 6.0 往日,到了2000年2月29日时,不许表露精确的日子。其余因为操纵体例的因为,comctl32.dll即使不革新到 4.72.2106.4 本子(及此后),那么在 nt 4 或视窗 95 操纵体例上,tdatetimepicker 将会用1752 替代一切的单数。 ---- 在数据库控件中,漏子和过滤(filter)因变量将 '00-1-1' 变换到 ’1900-1-1', 在用 locate 训令时,'00-1-1' 到 '99-1-1'功夫将被变换成 '20xx-1-11','30-1-1' 到 '99-1-1' 功夫将被变换到 '19xx-1-1'.因为是 locate 运用变数(variants)举行定位,日子定位并被没有经过 delphi 的运转时库举行,而是挪用了 win32 api 因变量变换到日子典型。这是因为 ole 机动效劳器东西的 ole 字串变换到日子典型的准则形成的。更加是当你调vartodatetime 因变量去试图从一包括日子的字串辨别出 tdatetime 典型时。少许数据库操纵在里面运用变体来索取本质数据,tdataset.locate 和 tparams 类将按照 ole 变体变换准则来实行简直操纵,而非经过delphi的"字串-日子"变换进程。 ---- 所以,delphi ide 情况和 dbexplorer 都在安置时设定了50 年的世纪窗口,其设定对独力运转的 sql explorer.exe 也灵验,在数据欣赏时的"2-4"年份变换都是如许设定. 然而,那些值是不妨窜改的。ide 的备案表项为 "hkey_currentuser\software\borland\delphi\4.x\ globals\twodigityearcenturywindow". dbexplorer.exe 的备案表项为 "hkey_currentuser\software\borland\database explorer\ 2.x\dbxform\twodigityearcenturywindow". ---- 即使将twodigityearcenturywindow变为0,那么 delphi3、delphi4、delphi5 对日子的证明都将如出一辙只处置两位数年份。 ---- j-midas (java midas) 和 j-tclientdataset 是依附 jbuilder 引擎对日子方法举行证明,以是对两位数的年份,jbuilder 只保持了 20 年的灵验期。 ---- 此刻回顾来看一下 delphi 3。因为天才不及,对仍还在运用他的步调员们来说,几何是有些悲观。然而,即使举行一番变革,再把 bde 晋级到 5.1 之上,或用 ado 2.1 包办 bde,仍旧不妨平常在低档机上栉风沐雨,身披上阵。 ----   咱们先看一下 delphi 3 中对年份处置的 eratoyear 因变量。该因变量归来一标记整形值。设置如次: function eratoyear(year: integer): integer; begin if syslocale.prilangid = lang_korean then begin if year <= 99 then inc(year, (currentyear + abs (erayearoffset)) div 100 * 100); if erayearoffset > 0 then erayearoffset := -erayearoffset; end else dec(erayearoffset); result := year + erayearoffset; end; ---- 咱们看到,delphi 对 2000 年并未加以商量,个中 year 获得年份的后两位。如许的话,到了2000 年,日子将回到往日。故而,必需将此因变量加以窜改,再不使咱们的日子变换能经过2000 年。开始,依照 delphi 从来的兼容性做法,该当在单位头部证明一 twodigitcenturywindow 的 byte 变量。在单位复试化时(initialization),把其附值为 50。其次,对 eratoyear 做如次变换: function eratoyear(year: integer): integer; begin if syslocale.prilangid = lang_korean then begin if year <= 99 then begin if year > twodigityearcenturywindow then inc(year, (currentyear + abs(erayearoffset)) div 100 * 100) else inc(year, (2000 + abs(erayearoffset)) div 100 * 100); end; if erayearoffset > 0 then erayearoffset := -erayearoffset; end else dec(erayearoffset); result := year + erayearoffset; end; ---- 而后对 scandate 因变量做相映的处置,以使其符合 2000 年过渡。 function scandate(const s: string; var pos: integer; var date: tdatetime): boolean; var dateorder: tdateorder; n1, n2, n3, y, m, d: word; eraname : string; erayearoffset: integer; ..... begin y := 0; m := 0; d := 0; result := false; dateorder := getdateorder(shortdateformat); erayearoffset := 0; if shortdateformat[1] = 'g' then // skip over prefix text begin scantonumber(s, pos); eraname := trim(copy(s, 1, pos-1)); erayearoffset := geterayearoffset(eraname); end else if ansipos('e', shortdateformat) > 0 then erayearoffset := erayearoffsets[1]; if not (scannumber(s, pos, n1) and scanchar(s, pos, dateseparator) and scannumber(s, pos, n2)) then exit; if scanchar(s, pos, dateseparator) then begin if not scannumber(s, pos, n3) then exit; case dateorder of if not scannumber(s, pos, n3) then exit; case dateorder of domdy: begin y := n3; m := n1; d := n2; end; dodmy: begin y := n3; m := n2; d := n1; end; doymd: begin y := n1; m := n2; d := n3; end; end; if erayearoffset > 0 then y := eratoyear(y); { 在这边 century window 表现效率 } if y <= 99 then begin if y > twodigityearcenturywindow then inc(y, currentyear div 100 * 100) else inc(y, 2000); end; end else ..... ---- 由此,delphi 3 仍旧不妨飞过 2000 年了,然而,inprise 倡导 delphi 3 的本子为 3.02。即使是 3.0 极端以次(不扶助 midas 1.,x) 象delphi 1.x(16位)、delphi 2.x(32位)不如径直晋级到 delphi 4.02. 有前提的喜好者用 delphi 5 就更好了。

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.