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

使用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:I ger;
begin
   dDate:=Sender.AsDateTime;
   DecodeDate(dDate,wYear,wMonth,wDay);
{测试输入掩码所包含的格式.}
   aryTestYMD:=’年’;
   if StrScan(PChar(Sender.EditMask),
   aryTestYMD[1])$#@60; $#@62;nil then
   iYMD:=1;
   aryTestYMD:=’月’;
   if StrScan(PChar(Sender.EditMask),
   aryTestYMD[1])$#@60; $#@62;nil then
   iYMD:=2;
   aryTestYMD:=’日’;
   if StrScan(PChar(Sender.EditMask),
   aryTestYMD[1])$#@60; $#@62;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])$#@60; $#@62;nil then
   iYMD:=1;
   aryTestYMD:=’月’;
if StrScan(PChar(Sender.EditMask),
   aryTestYMD[1])$#@60; $#@62;nil then
   iYMD:=2;
   aryTestYMD:=’日’;
if StrScan(PChar(Sender.EditMask),
   aryTestYMD[1])$#@60; $#@62;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.

时间: 2024-09-29 21:04:20

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

Oracle数据库日期型的插入(在PLSQL Developer上测试)

oracle|插入|数据|数据库 system/admin:数据库表scott方案下的empselect * from scott.emp  ORDER BY EMPNOINSERT INTO SCOTT.EMP (empno,HIREDATE) values(3,to_date('04-2月-2007','dd-Mon-yyyy'))INSERT INTO SCOTT.EMP (empno,HIREDATE) values(4,to_date('2007-1月-1','yyyy-Mon-dd'

mysql-使用Entity Framework链接Mysql数据库所有浮点型字段无法显示问题

问题描述 使用Entity Framework链接Mysql数据库所有浮点型字段无法显示问题 如题,不知道为何只要是Mysql中使用了浮点型字段,在EF在项目中都无法生成实体字段,不知各位大神有没有遇到过的或是解决方案,十分感谢. 解决方案 看看是不是映射的问题,两边不对应.换成decmal看看

my97 datepicker-My97 DatePicker 中可以使日期选择框和显示日期的文本框绑定在一起吗?

问题描述 My97 DatePicker 中可以使日期选择框和显示日期的文本框绑定在一起吗? 做项目是用easyui,引进了My97 DatePicker控件,在浏览器窗口大小改变,而弹出的dialog不能居中,我专门写了一个事件使得浏览器窗口改变时,使dialog居中,其中有的dialog中有选择时间的文本框.当弹出dialog,触发时间的文本框onfocus事件,弹出日期选择框,此时改变浏览器窗口,整个dialog移动居中,但是日期选择框并没有移动.所以,想请教各位大神,怎么使My97 Da

在WCF数据访问中使用缓存提高Winform字段中文显示速度

在我们开发基于WCF访问方式的Winform程序的时候,一般情况下需要对界面显示的字段进行中文显示的解析.如果是硬编码进行中文显示,那么除了不方便调整及代码臃肿外,性能上没有什么问题,但是不建议这样处理:一般情况下,我们把中文对照信息放到业务类里面去统一解析,但是这样会导致每次WCF访问方式请求解析中文化的操作耗费一定的响应时间.如果使用缓存存储中文字段的对照表,那么就不用每次请求WCF的数据访问,减少一些响应时间的消耗,提高用户体验效果. 1.使用硬编码方式的中文化解析操作 硬编码的方式,中文

jsp中对数据库日期类型的操作

问题描述 我用的是oracle的数据库给我一点代码看看就行了 谢谢 解决方案 2.日期到字符操作 select sysdate,to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual select sysdate,to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual select sysdate,to_char(sysdate,'yyyy-ddd hh:mi:ss') from dual select sy

日期型字段添加到SQL Server的问题?

问题描述 错误提示:该字符串未被识别为有效的DateTime.描述:HTMLCode<asp:TextBoxID="TitleAddTime"runat="server"></asp:TextBox>C#CodeprotectedvoidPage_Load(objectsender,EventArgse){TitleAddTime.Text=DateTime.Now.ToShortDateString().ToString();}protec

mysql数据库整型字段设计例子

只要做开发的,肯定创建过表,表字段用什么类型,长度是多少等.感觉没什么要说的,可是归纳总结一下,还有东西可说的. 数据类型 有符号 无符号 存储 bigint -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 0 到 2^64-1 (18446744073709551615) 8 字节 int -2^31 (-2147483648) 到 2^31-1 (2147483647) 0 到 2^32-1 (4294967295) 4

Delphi中的几种数据库引擎

Delphi中经常出现的词汇是ADO,BDE,dbExpress等等,那么他们之间到底有什么异同呢,Delphi中的数据库引擎又到底有多少种呢?也许应该从整体上把握一下,才能有的放矢.   Delphi一共提供四种数据程序的设计标准,分别是Borland Database Engine(BDE),ActiveX Data Object(ADO),dbExpress,InterBase Express.  (1)Delphi的BDE是一个在窗口环境下的32位数据库引擎.它也提供一组API函数,这些

关于数据库中日期时间型字段的操作问题

问题描述 我数据库用的是sQL2005,字段类型没有时期型,只有日期时间型,在操作时,这就产生了一个问题,我是以这个日期字段为主关键字的,可我在添加时,要先判断主键的唯一性,form表单用添加日期用的是控制dateTimePicker,这样如何与数据库中的字段比较,请指教.库中字段格式为2014-9-300:00:00 解决方案 解决方案二:至少可以dataTimePicker.Value.ToString("yyyy-MM-ddHH:mm:ss").Equals(sqlDataRea