在Delphi中处理数据库日期型字段的显示与输入

在Delphi中处理数据库日期型字段的显示与输入 (转)[@more@] 在使用Delphi进行数据库设计时,不可避免的会涉及到日期型字段的输入问题。不过与microsoft的Access 97中文版等相比,Delphi本身提供的日期型字段的显示和输入方式并不适合中国人的习惯。因此对于日期型字段的处理,大家提出了不少解决方法,但是处理结果在显示和输入上并不统一,例如显示时可以实现“yyyy年mm月dd日”的格式,但是在输入时还是要按照国外的习惯用“yyyy-mm-dd”的形式进行输入;而使用TdateTimePicker进行选择输入总嫌麻烦;有些方法还要修改系统的一些设置属性,因而在进行软件发布时要将系统的属性进行调整;采用第三方控件的方式则还要将控件打包发布。而且对于常用到的“1999年”、“1999年11月”等日期格式,没有进行相应的处理。这里我根据自己的实践,利用TField的OnGetText和OnSetText两个事件的结合,以期达到日期型字段的显示和输入的统一,并可以处理我们常见的“1999年”、“1999年11月”等日期形式的显示和输入,全部利用Delphi提供的事件实现,不需要修改任何系统设置。进行相应的扩展后,还可以用于时间的显示和输入,如“hh点mm分”等。同时,由于是直接控制TField的事件,所以不论使用TdbGrid还是用TDBEdit,都可以正常的进行统一处理,而不必分开考虑。采用类似的方法,还可以应用于非数据库应用程序中的日期输入。 

1 基本思想 

  利用TField的EditMask属性,将其同时作为显示和输入的掩码,在TField的OnGetText事件中处理日期字段的显示,而在OnSetText事件中处理输入值的有效性判断。为了重复利用代码,将OnGetText和OnSetText的事件处理过程调用的过程和函数放到一个独立的单元中。 

2 具体实现代码 

{显示和判断单元} 
unit DBDateEditMaskTrans; 
interface 
uses 
  windows, SysUtils, Controls, Forms,Db; 

 {日期型字段显示过程,在OnGetText事件中调用} 
 procedure DateFieldGetText(Sender: TField; var Text: String); 

 {日期型字段输入判断函数,在OnSetText事件中调用} 
 function DateFieldSetText(Sender: TField; const Text: String):Boolean; 

implementation 

procedure DateFieldGetText(Sender: TField; var Text: String); 
var 
   dDate:TDate; 
   wYear,wMonth,wDay: word; 
   aryTestYMD:Array [1..2] of Char ;{测试输入掩码用临时数组} 
   iYMD:Integer; 
begin 
   dDate:=Sender.AsDateTime; 
   DecodeDate(dDate,wYear,wMonth,wDay); 
{测试输入掩码所包含的格式.} 
   aryTestYMD:=’年’; 
   if StrScan(PChar(Sender.EditMask), 
  aryTestYMD[1])< >nil then 
   iYMD:=1; 
   aryTestYMD:=’月’; 
   if StrScan(PChar(Sender.EditMask), 
  aryTestYMD[1])< >nil then 
   iYMD:=2; 
   aryTestYMD:=’日’; 
   if StrScan(PChar(Sender.EditMask), 
  aryTestYMD[1])< >nil then 
   iYMD:=3; 

 case iYMD of 
  1:{输入掩码为:”yyyy年”的格式.} 
   Text:=IntToStr(wYear)+’年’; 
  2: {输入掩码为:”yyyy年mm月”的格式.} 
   Text:=IntToStr(wYear)+’年’+IntToStr(wMonth)+’月’; 
  3: {输入掩码为:”yyyy年mm月dd日”的格式.} 
   Text:=IntToStr(wYear)+’年’+IntToStr(wMonth)+’月’ +IntToStr(wDay)+’日’; 
  else {默认为:”yyyy年mm月dd日”的格式.} 
   Text:=IntToStr(wYear)+’年’+IntToStr(wMonth)+’月’ +IntToStr(wDay)+’日’; 
 end; 

end; 

function DateFieldSetText(Sender: TField; const Text: String):Boolean; 
var 
   dDate:TDate; 
   sYear,sMonth,sDay:String; 
   aryTestYMD:Array [1..2] of Char; 
   iYMD:Integer; 
begin 
 {获得用户输入的日期} 
   sYear:=Copy(Text,1,4); 
   sMonth:=Copy(Text,7,2); 
   SDay:=Copy(Text,11,2); 

 {测试输入掩码所包含的格式.} 
   aryTestYMD:=’年’; 
 if StrScan(PChar(Sender.EditMask), 
  aryTestYMD[1])< >nil then 
   iYMD:=1; 
   aryTestYMD:=’月’; 
 if StrScan(PChar(Sender.EditMask), 
  aryTestYMD[1])< >nil then 
   iYMD:=2; 
   aryTestYMD:=’日’; 
 if StrScan(PChar(Sender.EditMask), 
  aryTestYMD[1])< >nil then 
   iYMD:=3; 

 {利用Try…Except进行输入的日期转换} 
 try 
 begin 
 case iYMD of 
  1: {输入掩码为:”yyyy年”的格式.} 
   begin 
    dDate:=StrToDate(sYear+’-01-01’) ;{中文Windows默认的日期格式为:yyyy-mm-dd.下同} 
    Sender.AsDateTime:=dDate; 
   end; 
  2: {输入掩码为:”yyyy年mm月”的格式.} 
   begin 
    dDate:=StrToDate(sYear+’-’+sMonth+’-01’); 
    Sender.AsDateTime:=dDate; 
   end; 
  3: {输入掩码为:”yyyy年mm月dd日”的格式.} 
   begin 
    dDate:=StrToDate(sYear+’-’+sMonth+’-’+sDay); 
    Sender.AsDateTime:=dDate; 
   end; 
  else {默认为:”yyyy年mm月dd日”的格式.} 
  begin 
   dDate:=StrToDate(sYear+’-’+sMonth+’-’+sDay); 
   Sender.AsDateTime:=dDate; 
  end; 
  end; 
   DateFieldSetText:=True; 
  end; 
  except 
 {日期转换出错} 
 begin 
  Application.MessageBox(PChar(Text+’不是有效的日期!’), ’错误’,mb_Ok+mb_IconError); 
  DateFieldSetText:=False; 
 end; 
 end; 

end; 

end. 

{主窗口单元} 
unit Main; 

interface 

uses 
……{略去其他内容} 
procedure Table1BirthdayGetText(Sender: TField; var Text: String;DisplayText: Boolean); 
procedure Table1BirthdaySetText(Sender: TField; const Text: String); 
private 
{ Private declarations } 
public 
{ Public declarations } 
……{略} 
implementation 

{将自定义的单元包含进来} 
uses DBDateEditMaskTrans; 

{$R *.DFM} 
……{其他过程略} 
procedure TForm1.FormActivate(Sender: Tobject); 
{设置一个日期型字段的输入掩码,可以放到TField字段定义中。} 
begin 
   Table1.FieldByName(’Birthday’).EditMask:= ’9999年99月99日;1;_’; 
end; 

procedure TForm1.Table1BirthdayGetText(Sender: TField; var Text: String;DisplayText: Boolean); 
begin 
   DateFieldGetText(Sender,Text); 
end; 

procedure TForm1.Table1BirthdaySetText(Sender: TField; const Text: String); 
begin 
   if DateFieldSetText(Sender,Text)=False then 
   Abort; {转换不成功,日期 非法} 
end; 

end. 

posted on 2021-04-04 12:31  癫狂编程  阅读(297)  评论(0编辑  收藏  举报

导航

好的代码像粥一样,都是用时间熬出来的