说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Delphi系列的Y2K问题

HTML文档下载 WORD文档下载 PDF文档下载
Delphi系列的Y2K问题

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位数,而不是两位,这样才能除去世纪之交的二义性。

沿着这一思路 Delphi5中最重要的插件 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 就更好了。

Docker和Kubernetes或将加速SDN发展 前端开发框架三剑客—AngularJS VS. Backone.js VS.Ember.js 【CTO俱乐部读书会】《流程的永恒之道》辛鹏:企业的本质就是流程运营 紧扣微信研发痛点 2014微信开发者大会吸引大量外地参会者 Mobile First!jQuery UI组件集Wijmo五年最大更新 首届TCL杯HTML5智能电视—应用开发大赛火热开启! MDCC智能硬件征集关键词:智能家居、机器人、健康生活 采集颜色、自动同步,还有比这更牛叉的儿童触控笔么? AppCan移动平台:为企业移动化进程加速 学生强则国强,访天猫推荐算法大赛Top 9团队 Mozilla与三星之子——Servo特性解读 360天巡启动公测 打造新一代企业级无线安全解决方案 继Storm和Spark之后,Hortonworks添加对Kafka的支持 一周消息树:国产操作系统最快10月发布,并支持应用商店 技术团队看板方法实践的难点分析 SAP云服务加速转型:调动资源瞄准中国市场 开发测试全承包!移动应用开发工具Telerik平台 火火火火火!看HomeKit如何改变物联网和智能家居? MDCC应用与工具关键词:平台、社交、垂直、解决方案 Leap Motion正式入华 将发布第二代软件SDK 120万操作/秒Redis Cloud 集群单一服务器非基准测试程序 2014微信开发者大会顺利结束 TOP10优秀微信开发商名单公布 【最佳实践】通过DevOps确保可靠和有效的信息安全 2048 Hello World:跨平台快速应用开发Python框架Kivy Forrester:关于私有云的10个事实 2014年8月操作系统份额:Win 8.x大涨,Linux继续下跌 0代码、不编程—交互式网页设计工具VXPLO 揭秘Instagram Hyperlapse背后的技术 【CTO俱乐部在线教育研讨会】用互联网技术深入创新教育产品 降低门槛!Hybrid应用开发框架LigerMobile 下一代IT革命:微服务器和雾计算 请问各位同仁如何设置sybase anywhere服务器参数? 串口通讯能否用pb做成动态连接库的形式?(急) 怎样使Response.redirect打开一个新窗口 为什么环境变量替换不正确? 怎么打开foxpro中,通过剪切板考过去的图片,dbimage和image控件都不能打开,显示“bitmap is not valid” vaj中如何使用自己的JAR? 怎样改变当前窗口的大小,是当前窗口最大化? 高手争峰 如何把一个log文件读到数据结构中去 请教一个很菜的问题:) 这个程序有什么问题? 怎样做???? 简单问题,可就是搞不定!! 请问jsp中servelet在win2000中的设置方法,需要下载什么类库文件么? 一个新问题,那就是点击工具栏的退出按钮以后只退出当前打开的窗口,而不是整个应用! 如何在 index.htm 中引用 count.asp ? 远程数据库访问的问题--亟待高手们解答 王国荣的电子信箱是哪里? 我的程序生活 先给50分,稍后在加:我正在做一个系统,需要做到每次开机时提醒用户有哪些事情要做! [Tips]获取Memo&Richedit中光标坐标的最简单方法! 急急,如何才能把图片的底色与窗口的底色自然地融为一体? 如何改变按钮的颜色? 在mtml help workshop 中如何制作带上下文关联ID的帮助 调试程序时,控制台程序与直接建立的C++程序有区别吗? 给菜鸟推荐本书 VB调用外部DLL问题 【洗心革面,重新做人,割发断指,庄严声明】 从今以后 kook 不近女色,不灌疯水,以 panda_w 为榜样,苦练VC,研习汇编,做一个 CSDN 的正面典型! 谁有ULTRAEDIT 的注册码 能否推荐几本关于VB提高和关于VB数据库的书 紧急问题,关于SSL通过MS PROXY String类的问题 连接数据库的东东真是奇怪! 如何打开pdm格式文件 ===========灌水传说=========== 奇怪的问题,怎么办? 呵呵,初学者,请多多指教 剖 尸 小问题:自定义组件的显示 怎样打印picturebox中的内容??? 关于Datawindow的Group的问题 谁能告诉我 Delphi6的序列号 紧急问题,关于SSL通过MS PROXY! 请问,如果用ASP作邮件发送,接收的功能,win2k怎么设置????????? 各位大侠,谁用visual age for java3.5 开发过 ejb呀,发个例子及过程给我好吗?没例子,有过程也可以!以分做谢! 哪位大哥能将解一下notify()和wait()的用法 我用delphi做的工程是一个exe+n个DLL的,请问datamodule放哪里合适;请高手们详细讲讲. 如何除去这可恶的标题? 请问如何取得动态数组的维数,换言之如何取得动态数组的值? 1000M,一会儿就满了,怎么回事? 求助!数据管道问题 小红在班级小银行储蓄的钱数是小刚的2分之3,后来小红又存进4元钱,而小刚取出6元钱此时小红的钱数是小刚的钱数的4分之3,现在小刚,小红各储蓄多少元? 买同一个书包,小明花去了他所带钱的5/8,小红花去了她所带钱的3/5求两个人所带钱的比,如果是方程就要把解的过程详细的打出来好么 有一种植物的茎是红色的,叶子是绿色的,请问是什么花啊 小红体重与小亮的比2比3.小亮与小刚体重的体重3比4.那么小红和小刚的体重比是多少 小明和小红一共有250元,当小明花掉他自己的5分之2,小红花掉40元后两人剩下的钱相等求小明原来的钱是多少? 一种红色的花 花朵像纸做的,谢了以后变成暗紫色.叶子有点像南瓜的叶子. 小红的存钱是小刚的三分之二,小红存进4元,而小刚取出6元,这时小红是小刚的四分之三,小红和小刚各?元 小红和小明带同样多的钱去买练习本.小红花光了自己的钱,并向小明借1元钱,刚好买了8本练习本 有绿叶子,还有红叶子,红叶子中间长着黄色的长长的棒棒,是什么花啊? 小红在班级小银行存储的钱是小刚的三分之二,后来小红有存进4元,而小刚取出6元钱小红在班级小银行储蓄的钱数是小刚的三分之二,后来小红又存进4元钱,而小刚取出6元钱此时小红的钱数是 小莉买文具和图书共用去54元,其中买图书的钱数比买文具的2倍还多3元,买文具和图书各用多少元? 透过红色玻璃看黄色的花绿色的叶呈什么颜色 修改病句:国庆节那天,天安门前挂满了五颜六色的红旗 小林在少儿银行存款50元,小刚存款88元,以后小林每月存5元,小刚每月存12元,几个月后小刚存款数是小林存款数的2倍?求算式,急!谢谢 假期里,小莉用一天学习时间的45%看课外书,她每天看课外书时间是90分,小莉每天用于学习的时间有多长?小莉每天用于学习的时间占一天的百分之几? 广场上到处是五颜六色的红旗(修改病句) 小红在班级小银行储存的钱数是小刚的3分之2,后来小红又存进4元钱,而小刚取出6元钱此时小红的钱数是小刚4分之3,现在小刚小红储存多少元钱? 一.1.小星和小莉看课外书,小星看了40页,是小莉所看页数的5分之4.小莉看了多少页?2.小星和小莉看课外书,小星看了40页,比小莉所看的页数多4分之1.小莉看了多少页?3.小星和小莉看课外书,小星 节日的校园里,插满了五颜六色的红旗.(修改病句) 小红在班级小银行储蓄的钱数是小刚的2分之3,后来小红又存进4元钱,而小刚取出6元钱此时小红的钱数是小刚的钱数的4分之3,现在小刚,小红各储蓄多少元?小红在班级小银行储蓄的钱数是小刚 假期里,小莉用一天学习时间的45%看课外书,她每天看课外书的时间是90分.小莉 修改病句:校园里生满了白的、红的、黄的等五颜六色的花. 小红在班级小银行里储蓄的钱数是小刚的三分之二,后来小红又存进4元,而小刚取出6元,此时小红的钱数是小刚钱数的四分之三,现在小刚.小红各储蓄多少元? 小莉看一本书,5天看了全书的20%,照这样计算,把剩下的书全部看完还需多少天? 春风吹得满山的桃树绽开了五颜六色的花,一片火红,非常精彩.修改病句按题修改 小红在班级小银行储蓄的钱数是小刚的三分之二,后来小红又存进4元钱,而小刚取出6元钱此时小红此时小红的钱数是小刚的钱数的4分之3,现在小刚,小红各储蓄多少元?要方程和算式不要方程 要 小明和小莉出生于1999年10月份,他们的出生日期不是同一天,但都是星期三,且小明比小莉出生早,两人出生日期之和是22,那么小莉的出生日期是( )A:15日 B:16日 C:17日 <修改病句> 1.公园里生长着各种树和五颜六色的鲜花请修改以上病句 小红的零花钱比小刚多4分之1,小晓的零花钱比小刚的少3分之1.小红和小晓的零花钱相差14元.三人各有零花钱多少元? 小明和小莉出生于1999年12月份他们的出生日他们的出生日不是同一天,但都是星期一 病句:春天公园里五颜六色的花,竞相开放.请问怎么修改?急 这次考试小红考了98分.小红比小刚的分数的七分之八还多2分.你知道小刚考了多少分吗? 小明和小莉出生于1998年12月份,他们的出生日不是同一天,但都是星期五,且小明比小早,两人出生日期之和是29,那么小莉的出生日期是()A、15号 B、16号 C、17号 D、18号 孩子穿着红衣服和白帽子(修改病句) 小红捐360小刚是小红的9分之10小刚捐的是小红的8分之7小刚捐了多少元? 《黄冈小状元》的问题:小明买了2kg梨,共22个;小莉买了3kg梨,共24个,两个人买的梨平均每个各是多少千克?谁买的梨大些? 改病句:他穿着一身崭新的衣服和帽子. 在一次跳绳比赛中小明跳了92个 小红跳了85个 小刚跳了87个 小敏跳了几个 注.我跳的个数是我们5个的平均数上面的写错了 在一次跳绳比赛中小明跳了92个 小红跳了85个 小刚跳了87个 小敏 【急】小明和小丽出生于1999年12月份,他们的出生日不是同一天,但都是星期五,且小明比小莉出生早,两人出生日期之和是22,那么小莉的出生日期是?(一元一次方程解) “他今天穿着一件新衣服和一顶新帽子”怎么改病句? 学校举行一分钟跳绳比赛,小红跳了120下,小玲跳的下数是小红的八分之九,小刚跳的下数比小玲少十五分之二小刚跳的下数比小玲少多少下?不用方程 刚买了一盆花,不知道是什么花,请问谁知道这是什么花? 改病句:刘艳同学今天真漂亮,穿着新衣服和帽子 一个数是2和3的倍数这个数是 这两盆花是什么花 今天,小芳穿着新衣服和新帽子高高兴兴去上学.(修改病句) 一个数同时是2 3的倍数,这个是数有什么的特征? 我有一盆花,但是不知道什么名字,请问下这是什么花, “尽管明天下雨,我们还要去爬山.”修改病句卷子上的题目急 2和3的倍数的共同特征是什么 中间叶子是红色的周围是绿色的一年四季都是这样是什么花?中间叶子是红色的周围是绿色的一年四季都是这样!买时老板说是叫富贵什么?不记得了,不知道哪位朋友知道是什么花,知道他的养 看,空中有一道五颜六色的彩虹.(修改病句) 三位同学购物,小明花去钱数的1/2等于小琳花去钱数的1/3,小琳花去钱数的3/4等于军军花去钱数的4/7,结果军军比小明多花93元,他们三人共花了多少钱?急 花像叶子一样是红色的,叶子是绿色的是什么植物,适合什么样的环境生存, 修改病句:明天上午去爬山 小明和小红共带了200元去购物,购完后2人剩下的钱正好相等,已知小明花去的和原来的钱比是3比7,小红花去小红花去的和原来的比是9比13,小明花去多少元 这是什么树?绿色树叶,红色的花 脱下了五颜六色的衣裳 小红花和小明去超市购物,小红买了6个果冻,每个2.1元.小明买了2块巧克力,比你多花3元,每块巧克力多少元 绿色花叶还带红色花叶是什么花?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn