本文整理自网络,侵删。
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,DateUtils, ComCtrls;
type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; DateTimePicker1: TDateTimePicker; Button3: TButton; DateTimePicker2: TDateTimePicker; Button4: TButton; Button5: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementationuses uDateTimeByc;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);var dt1:TDateTime;begin {**** 格式1:2019/07/02 10:10:10 格式2:2019-07-02 10:10:10
程序里不统一,在字符串和日期两种类型转换时候会报错 格式1是win7默认格式, 格式2是软件里常用格式
****}
//坑:delphi的日期是从1899-12-30 00:00:00开始 memo1.Lines.Add(FormatDateTime('yyyy-MM-dd hh:mm:ss',0));//1899-12-30 00:00:00 //sql server里则是 1900-01-01 00:00:00 其他数据库没做测试 { declare @dt datetime set @dt=0 print convert(varchar(30),@dt,120) --输出1900-01-01 00:00:00 --所以不能在delphi里用sql语句传递数值型的日期,但传递TDateTime给sql server的datetime类型可以正常 update 表 set 列1=12345 where 条件 这种数值类型,就会有时间偏差 update 表 set 列1='2019-07-07' where 条件 推荐这种写法 ,数据库里日期格式不区分分隔符,都能识别
} //重点:数据库里不能传递毫秒级的,delphi最好把毫秒去掉全是000,不然很容易出现这种错误:record is not found or changed by another //比如adoquery.fieldbyname('DT').asDatetime:=Now;这样带毫秒级别,下次修改记录就会出问题
//日期类型转换成字符串 memo1.Lines.Add(FormatDateTime('yyyy-MM-dd hh:mm:ss',Now));//Now取电脑当前时间 //注:如果电脑短日期格式是YYYY/MM/dd 则,即使这里用-,结果也会是2019/07/02 10:10:10
//日期分解合并函数: //EncodeDateTime()和DecodeDateTime(); 用的不多
//字符串转换成日期: //StrToDateTime() //这个函数,当电脑短日期格式和字符串格式不一致会报错:日期格式不对 // 比如短日期格式:2019\07\02 写成这样 StrToDateTime('2019-07-02')就报错 //同样,数据库adoquery.fieldbyname('DT').asstring:='2019-07-02'//也会报错
//推荐函数: //不管是-还是/或者英文的日期格式都能识别 dt1:=VarToDateTime('2019-01-01'); Memo1.Lines.Add(FormatDateTime('yyyy-MM-dd hh:mm:ss.zzz',dt1));
end;
procedure TForm1.Button2Click(Sender: TObject);var dt1,dt2:TDateTime;begin Memo1.lines.Add(ConvertDT2Str(Now)); //参数默认值方便使用'YYYY-MM-DD hh:mm:ss' Memo1.lines.Add(ConvertDT2Str(Now,'YYYY-MM-DD'));
//时间间隔计算 浮点计算偏差解决办法 dt1:=VarToDateTime('2019-07-02 10:10:10'); dt2:=VarToDateTime('2019-07-02 10:11:12'); CalcTimeSpan2(dt1,dt2);//计算出的是秒,分的话div 60 依次类推end;
procedure TForm1.Button3Click(Sender: TObject);var dt1:tdatetime; s:string;begin {kind属性改成Date还是time
日期控件最好只用datetime属性,即使有的日期控件有date属性和time属性, 控件属性直接:=赋值,不会触发相关事件,比如,赋值了datetime为 '2019-01-01 13:00:00' 那么date属性应该是2019-01-01,time属性是13:00:00 但有些控件bug,不会跟着变, 所以只用datetime肯定没错
} datetimepicker2.Format:='yyyy-MM-dd hh:mm:ss';//hh小写是12小时制 datetimepicker2.Format:='yyyy-MM-dd HH:mm:ss';//HH大写是24小时制 datetimepicker2.DateTime:=VarToDateTime('2019-01-01 13:00:00');
s:=FormatDateTime('yyyy-MM-dd',datetimepicker1.datetime)+' '//取1的日期 + FormatDateTime('hh:mm:ss',datetimepicker2.datetime);//取2的时间 dt1:=vartodatetime(s);//这样能保证肯定不会错end;
procedure TForm1.Button4Click(Sender: TObject);begin //设置统一的软件时间格式,一般放在工程最前面,比如Main窗体的create下 SetSysDateFormat;end;
procedure TForm1.Button5Click(Sender: TObject);begin Memo1.lines.Add(FormatDateTime('yyyy-MM-dd hh:mm:ss',Now)); Memo1.lines.Add(FormatDateTime('yyyy/MM/dd hh:mm:ss',Now)); //电脑默认是/时候上面结果不同 //电脑短日期改成yyyy-MM-dd,则上面结果相同 ,都是 yyyy-MM-dd
Memo1.lines.Add(FormatDateTime('yyyyMMdd',Now));//不带分隔符
//下面自己写的 Memo1.lines.Add(ConvertDT2Str(Now,'yyyy-MM-dd hh:mm:ss','-')); Memo1.lines.Add(ConvertDT2Str(Now,'yyyy/MM/dd hh:mm:ss','/'));
Memo1.lines.Add(ConvertDT2Str(Now));//参数默认值
end;
end.
uDateTimeByc.pasunit uDateTimeByc;
interfaceuses DateUtils,SysUtils;
//日期转字符串byc 2019-4-28 12:23:57 function ConvertDT2Str(ADT:TDateTime;AFormat:string='YYYY-MM-DD hh:mm:ss'; ADTSeparator:string='-'):string;
//时间戳的方式解决SecondsBetween或SecondSpan之类的double类型计算误差bycfunction CalcTimeSpan2(AOld,ANew:TDateTime):int64;
//设置软件格式byc,可以在main窗体的create下加//(目前只用预编译指令写了d7和else,2007、2009、2010,d6及一下未知)procedure SetSysDateFormat;
implementation
//2019-4-28 12:23:57function ConvertDT2Str(ADT:TDateTime;AFormat:string='YYYY-MM-DD hh:mm:ss'; ADTSeparator:string='-'):string;var sSysSeparator:string; rRes:string;begin sSysSeparator:=FormatDateTime('YYYY-MM-DD',0); sSysSeparator:=sSysSeparator[5]; rRes:=FormatDateTime(AFormat,ADT); rRes:= StringReplace(rRes,sSysSeparator,ADTSeparator,[rfReplaceAll]); Result:= rRes;end;
function CalcTimeSpan2(AOld,ANew:TDateTime):int64;var dt1,dt2:TDateTime; UnixDT1,UnixDT2:int64; rTmp:int64; rRes:int64;begin rRes:= -1; try if AOld begin dt1:=AOld; dt2:=ANew; end else begin dt1:=ANew; dt2:=AOld; end; UnixDT1:=DateTimeToUnix(dt1); UnixDT2:=DateTimeToUnix(dt2); rTmp:=UnixDT2-UnixDT1; rRes:=rTmp except rRes:=-1; end; result:= rRes;end;
procedure SetSysDateFormat;begin // 设置WINDOWS系统的短日期的格式 //SetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, 'yyyy-MM-dd'); //Application.UpdateFormatSettings := False; // 设定程序本身所使用的日期时间格式
//在程序create里设置一下时间格式 {$IFDEF VER150} //delphi 7 ShortDateFormat := 'yyyy-mm-dd'; LongDateFormat := 'yyyy-mm-dd'; ShortTimeFormat := 'hh:nn:ss'; LongTimeFormat := 'hh:nn:ss'; DateSeparator := '-'; TimeSeparator := ':'; {$ELSE} //其他版本(xe以上版本 {d6以下不常见版本适当修改,2007,2009,2010三个版本基本没接触过,未测试用哪种方法)} with FormatSettings do begin ShortDateFormat := 'yyyy-mm-dd'; LongDateFormat := 'yyyy-mm-dd'; ShortTimeFormat := 'hh:nn:ss'; LongTimeFormat := 'hh:nn:ss'; DateSeparator := '-'; TimeSeparator := ':'; end; {$ENDIF}end;end.
感谢:天苍苍野茫茫(964219545) 分享
补充:格林时间 linux时间戳
//d7下,默认当前时区多8小时DateTimeToUnix(Now)-8*60*60 =时间戳UnixToDateTime(时间戳+8*60*60)=时间
d10 DateTimeToUnix(Now,false)true 代表的是本地时间,false是格林时间d10的true=d7的默认=本地时间,多8小时
设置软件时间格式在程序create里设置一下时间格式 ShortDateFormat := 'yyyy-mm-dd'; LongDateFormat := 'yyyy-mm-dd'; ShortTimeFormat := 'hh:nn:ss'; LongTimeFormat := 'hh:nn:ss'; DateSeparator := '-'; TimeSeparator := ':';xe版本需要添加前缀with FormatSettings dobegin ShortDateFormat := 'yyyy-mm-dd'; LongDateFormat := 'yyyy-mm-dd'; ShortTimeFormat := 'hh:nn:ss'; LongTimeFormat := 'hh:nn:ss'; DateSeparator := '-'; TimeSeparator := ':';end;
错误写法:procedure SetSysDateFormat;var fs: TFormatSettings;begin // 设置WINDOWS系统的短日期的格式 SetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, 'yyyy-MM-dd'); Application.UpdateFormatSettings := False; // 设定程序本身所使用的日期时间格式 fs.LongDateFormat := 'yyyy-MM-dd'; fs.ShortDateFormat := 'yyyy-MM-dd'; fs.LongTimeFormat := 'hh:nn:ss'; fs.ShortTimeFormat := 'hh:nn:ss'; fs.DateSeparator := '-'; fs.timeSeparator := ':';end;
时间间隔_加法
var
aa,bb,cc:TDateTime;
begin
bb:=VarToDateTime('2018-01-01 13:13:05');
aa:=VarToDateTime('2018-01-01 13:13:00');
cc:= incsecond(aa,5);
Memo1.Lines.Add(FloatToStr(SecondsBetween(bb,aa))) ;
Memo1.Lines.Add(formatdatetime('yyyy-MM-dd hh:mm:ss',cc)) ; //加法计算时间差也可以没误差
end;
这样加法
旧时间+间隔 >= dtNow 也可以,或者用函数里的
如果需要计算时间差,就只能用函数里的时间戳的方法
相关阅读 >>
在xp/2k 下实现 win+ctrl+del 等键的屏蔽的方法
Delphi 从 twebbrowser中获得当前输入处的链接
Delphi xe(indy10)tidbytes转ansistring的实现
更多相关阅读请进入《Delphi》频道 >>