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;
implementation
uses 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.pas
unit uDateTimeByc;
interface
uses 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类型计算误差byc
function CalcTimeSpan2(AOld,ANew:TDateTime):int64;
//设置软件格式byc,可以在main窗体的create下加
//(目前只用预编译指令写了d7和else,2007、2009、2010,d6及一下未知)
procedure SetSysDateFormat;
implementation
//2019-4-28 12:23:57
function 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 do
begin
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 也可以,或者用函数里的
如果需要计算时间差,就只能用函数里的时间戳的方法