关于两个日期之间的时间如何求(100分)

  • 主题发起人 主题发起人 54weige
  • 开始时间 开始时间
5

54weige

Unregistered / Unconfirmed
GUEST, unregistred user!
关于两个日期之间的时间如何求
格式是到期日期时间2006-6-19 23:45:24 和现在时间
我想写个程序,showmessage出他们的时间差,然后程序运行中,若时间到自动关闭程序!会的朋友请指点下小弟弟,小弟弟将感激不尽!
 
时间不就是实数吗?
ADATE,BDATA:TDateTime,

TDateTime 的整数部分是日期,天,小数是时间。
delta:=BDate-ADate;
不过时间不知道是不是不能精确,你就精确一下了。
 
SecondsBetween(const ANow, AThen: TDateTime): Int64
够精确了吧
 
Returns the number of seconds between two specified TDateTime values.

Unit

DateUtils

Category

date/time routines

function SecondsBetween(const ANow, AThen: TDateTime): Int64;

Description

Call SecondsBetween to obtain the difference, in seconds, between two TDateTime values. SecondsBetween counts only entire seconds that have elapsed. Thus, SecondsBetween reports the difference between 9:00:00 AM and 9:00:00:999 AM as 0 because the difference is one millisecond short of an entire second.
 
能精确到天就行,比如我知道了现在网站我的剩余时间为2天,那2天后我的程序如何关闭 ?如何写代码?
 
DaysBetween(const ANow, AThen: TDateTime): Integer;

比如
if DaysBetween(YourDefineDateTime, Now) >= 2 then
Yourcode;
 
日期型的可以相减
 
我只知道还有2天时间到,如何实现2天后程序自动关闭?
 
借花:
if DaysBetween(YourDefineDateTime, Now) = 0 then
application.terminate;
 
给你一个计算两个时间差的函数~~
function TimeDiff(ETime, // 结束时间
BTime: TDateTime; // 开始
RType:Integer // 返回结果类型,0为天,1为小时,2为分钟,3为秒
):Integer; // 返回值
var
d,h,m,s: Integer;
begin
TimeMinus(ETime,BTime,d,h,m,s); // van 20031129 修改参数传递错误
case RType of
0: Result := d;
1: Result := d*24 + h;
2: Result := (d*24 + h)* 60 + m; // van 20030910 修改计算错误
3: Result := ((d* 24 + h)*60 + m)*60+s;
end;
end;
 
两个类相减就可以
 
大家照我说的把代码贴一下,小弟火候不够,还希望大家多多锤炼!
比如我现在的时间是2006-6-20 我pos了网页代码里的时间还有2天到期,那该如何表达2天后关闭程序?
 
直接相减就可以了
 
问题是如何相减....................
 
我的思路~~

由于时间类型为 type TDateTime = type Double;

Double类型~~

所以我们可以这样计算~~

double := trunc(日期) - trunc(日期)

你再转换成 TDateTime类型 ~~

上面只是一种方法~~

其实日期-日期就可以,不过你有一个2天你没法计算,所以我的上题公式可以算出来~~


var
I: Double;
s: TDateTime;
begin
I := Trunc(Date) + 2;
s := FloatToDateTime(I);
ShowMessage(DateTimeToStr(s));

呵呵。加分~~
 
嘿嘿,其实我想100分问到更多的问题,没办法,谁叫我分少呢。
就是www.tybird.com/jinqu.asp输入123然后点提交,得到的年月日时分秒如何保存在edit1.text里,然后减现在的时间,若时间过了,那么就停止程序.希望各位大大们把代码贴出来啊,再次强调,本人分少,所以对不起大家了,呵呵!
 
能说更清楚点吗。
你的要用在asp上面还是delphi开发的程序里啊?

另:你说的剩下2天,一般都有个习惯性误差,1天多我们也可以说2天,2天多我们认为说2天也是正常的,究竟要严格到哪个程度?取整还是四舍五入?
 
流程:
1: 利用Idhttp.post方法,对www.tybird.com/jinqu.asp里的那个表单进行提交
2: 分解提交后源代码,得到还有几天,或几月几日什么的, 反正就是网站的信息
3: 把信息显示到你的edit1.text里
4: 再进行相关的判断,
5: 给我送分~~~~
6: 不送分打PP

^_^
 
话题1131624的标题是: 如何计算两个TDateTime的相隔时间(年、月、日、时、分、秒)? (100分)
分类:系统相关 叮叮当当 (2002-05-29 20:38:00)
要求编制一个过程返回两个TDateTime的经过时间(年、月、日、时、分、秒)
procedure DateTimeDiff(const T1, T2: TDateTime; out Y, M, D, H, N, S, MS: Word);
T2>T1,例如输入
T1=2002-5-29 20:30:10.100
T2=2002-5-29 20:31:11.000
返回 Y、M、D、H、N、S、MS
为: 0、0、0、0、1、0、900

VB里的TimeDiff函数是能完成类似功能的,Delphi的DateUtils里的函数我都查过了,没有适合的。[:(]
这个问题我想了几乎一个下午!如果用SecondsBetween函数得到经过的秒数再用整数除法计算分、时、日……会碰到闰年的问题。

mlzhou (2002-05-29 20:49:00)
var
ti,t2: TDateTime;
Year1, Month1, Day1, Hour1, Min1, Sec1, MSec1,
Year2, Month2, Day2, Hour2, Min2, Sec2, MSec2,
dYear, dMonth, dDay, dHour, dMin, dSec, dMSec: Word;
DecodeDate(t1, Year1, Month1, Day1);
DecodeTime(t1, Hour1, Min1, Sec1, MSec1);
DecodeDate(t2, Year2, Month2, Day2);
DecodeTime(t2, Hour2, Min2, Sec2, MSec2);
dYear:=Year1-Year2;
.......




qdyoung (2002-05-29 20:55:00)
t=T1-T2;
d=trunc(t);
t=t-d;
decodetime(t,h,n,s,ms);
decodedate(d,y,m,d)
decodedate(0,y0,m0,d0)
y,m,d与y0,m0,d0要减一下,这个不难吧

-------------------
http://www.8421.org

lynu (2002-05-29 21:18:00)
为什么老有人问这样的问题.
你只要明白一个事情:TDateTime=double

bubble (2002-05-29 21:41:00)
hi,你要知道这个就行了,
当初我想算两个Date之间有多少天,
后来发现两个Date相减就行了,
你有启发了么??
time也是一样啊。

雪鹰 (2002-05-29 21:45:00)
procedure TimeDiff(FromDate,ToDate:TDateTime;Var DayGo:integer;var TimeGo:Ttime);
var
aTimeDiff:TDateTime;
begin
aTimeDiff:=ToDate-FromDate;
DayGo:=(trunc(aTimeDiff)); //逝去的日子
TimeGo:=aTimeDiff;//逝去的时间.
//注意没有日期部分的时间TIMEGO STRTODATE会成1887什么的,所以用TIMEGO要用TIMETOSTR
end;


雪鹰 (2002-05-29 21:47:00)
随便给点分吧,好久没混分了,就是因为答了没人给分^_^

叮叮当当 (2002-05-29 21:55:00)
我要用做出来的DateTimeDiff过程显示“现在已经正常运行XX天XX月XX日XX小时XX分XX秒”,所以单纯地把年月日时分秒分离出来相减返回是不符合要求的。

我们先不管毫秒罢。
比如输入
T1=2002-5-31 20:59:59
T2=2002-6-01 19:00:00

会返回什么?
mlzhou的程序会返回“0年1月30天1小时59分59秒”,而正确的应该是“0年0月0天22小时0分1秒”

qdyoung的程序好像是正确的,我试试。

mlzhou (2002-05-29 21:57:00)
原来是这样,我的错了。

xiao_ping (2002-05-29 22:11:00)
这个问题我问过
http://www.delphibbs.com/delphibbs/dispq.asp?lid=678320

叮叮当当 (2002-05-29 22:23:00)
qdyoung的程序也有问题,时间倒没有问题,日期用简单的相减就会有问题!

TO: xiao_ping
你的问题最后接受的是menxin的答案么?

苦虫 (2002-05-29 22:31:00)
二个相减,再用decode,唉~

xiao_ping (2002-05-29 22:49:00)
是。

叮叮当当 (2002-05-29 23:15:00)
TO: xiao_ping
menxin的程序最后好像也有问题(计算天数的地方):
r3:=DayOf(Date2)-DayOf(Date1) +IfThen(DayOf(Date1)<=DayOf(Date2),0,DaysInMonth(StartOfTheMonth(Date2)-1));
假如
Date1=2000-01-30
Date2=2000-03-31

StartOfTheMonth(Date2)=2000-03-01
StartOfTheMonth(Date2)-1=2000-02-29 (TDataTime的整数部分就是天数,减1就等于天数减1)
DaysInMonth(StartOfTheMonth(Date2)-1)=29
DayOf(Date1)<=DayOf(Date2) 成立,因此 r3:=DayOf(Date2)-DayOf(Date1) +29=31-30+29=30 (天)
这是错误的,应该是“2个月零1天”。

Pearl. (2002-05-29 23:23:00)

procedure timediff(FromDate, ToDate: TDateTime; var Y, M, D, H, N, S, MS: word);
var
d: TDateTime;
begin
d := ToDate-FromDate;
decodedate(d, y, m, d);
decodetime(d, h, n, s, ms);
end;

linsb (2002-05-29 23:33:00)
T1:=StrToDateTime('2002-5-29 20:30:10.100');
T2:=StrToDateTime('2002-5-29 20:31:11.000');
//为: 0、0、0、0、1、0、900
td:=t2-t1;
DecodeTime(td, Hour, Min, Sec, MSec);
DecodeDate(td, Year, Month, Day);
Label1.Caption:=IntToStr(floor(td))+'-'+IntToStr(hour)+'-'+IntToStr(min)+'-'+IntToStr(sec)+'-'+IntToStr(msec);
//为: 0-0-1-0-900
floor(td))为相差天数,如果超过30天月数加一,如果月数大于12年数加一进行折算。


Oldtiger (2002-05-29 23:37:00)
明白TdateTime是Double就好了!
两个TDateTime相减,结果的整数部分就是天数
小数部分就是时分秒
例如,相减结果为3.256
则时间间隔为3天+0.256*24*60*60秒
再把这个秒数折算一下就是时分了!

叮叮当当 (2002-05-29 23:47:00)
TO: Pearl.
你想让我一上来就显示“已运行1899年12月30天……”啊?[:D]

TO: Oldtiger
我已经明白“TdateTime是Double”了。
也知道怎样计算经过的天数,可我不知道怎么把类似“768天”的计算结果转为显示“XX年XX月XX天”。[:(]要完成这个可没有想像的那么简单,因为可能要牵涉到闰年计算。

bigroute (2002-05-29 23:53:00)
formatdatetime('yyyy-mm-dd hh:ss:nn:zzz',t1-t2);

stucxm (2002-05-30 0:06:00)
只能确定可经过某年某月某日,但不能确定经过多少年多少月多少日,因为一年、有多
少日是不固定的。

冰封 (2002-05-30 0:13:00)
to stucxm : 可以的。
to 叮叮当当:
可以对menxin的程序稍加修改就行了。
r3除与DaysInMonth(StartOfTheMonth(Date2)-1)整数部分
加到月数,余数就是天数。
程序就不写了,这两天手指痛。

叮叮当当 (2002-05-30 0:21:00)
TO: 冰封
没听懂,我的脑子现在已经满是浆糊了。。。

Pearl. (2002-05-30 0:28:00)
To: 叮叮当当
加一句dec(y, 1899)不就可以了?

stucxm (2002-05-30 0:30:00)
Sorry,我误解了,因为可以以起始日期开始推算的。

hamsoft (2002-05-30 0:31:00)
我有个现成的vcl,现奉献出来:

{*************************************************************}
{ DateTime Calculator component for Delphi 16/32 }
{ Version: 1.3 }
{ Author: Aleksey Kuznetsov }
{ E-Mail: info@utilmind.com }
{ Home Page: http://www.utilmind.com }
{ Created: May, 12, 1999 }
{ Modified: August, 3, 1999 }
{ Legal: Copyright (c) 1999, UtilMind Solutions }
{*************************************************************}
{ TDTCalc (in English) }
{ Component for calculation of amount of years, months, days, }
{ hours, minutes, seconds and miliseconds past between two }
{ time intervals. }

{ PROPERTIES: }
{ StartTime, EndTime: TDateTime; - Range of time interval. }
{ READ ONLY PROPERTIES: }
{ Years: Int64 }
{ Months: Int64 }
{ Days: Int64 }
{ Hours: Int64 }
{ Minutes: Int64 }
{ Seconds: Int64 }
{ MSeconds: Int64 }
{*************************************************************}
{ Please see demo program for more information. }
{*************************************************************}
{ IMPORTANT NOTE: }
{ This software is provided 'as-is', without any express or }
{ implied warranty. In no event will the author be held }
{ liable for any damages arising from the use of this }
{ software. }
{ Permission is granted to anyone to use this software for }
{ any purpose, including commercial applications, and to }
{ alter it and redistribute it freely, subject to the }
{ following restrictions: }
{ 1. The origin of this software must not be misrepresented, }
{ you must not claim that you wrote the original software. }
{ If you use this software in a product, an acknowledgment }
{ in the product documentation would be appreciated but is }
{ not required. }
{ 2. Altered source versions must be plainly marked as such, }
{ and must not be misrepresented as being the original }
{ software. }
{ 3. This notice may not be removed or altered from any }
{ source distribution. }
{*************************************************************}
unit DTCalc;

interface

uses
{$IFDEF Win32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
SysUtils, Classes;

type
TDTCalc = class(TComponent)
private
FStartTime, FEndTime: TDateTime;
FYears, FMonths, FDays, FHours, FMinutes: Int64;
FSeconds, FMSeconds: Int64;
procedure SetStartTime(Value: TDateTime);
procedure SetEndTime(Value: TDateTime);
procedure Calculate;
procedure SetNone(Value: Int64);
public
property Years: Int64 read FYears;
property Months: Int64 read FMonths;
property Days: Int64 read FDays;
property Hours: Int64 read FHours;
property Minutes: Int64 read FMinutes;
property Seconds: Int64 read FSeconds;
property MSeconds: Int64 read FMSeconds;
published
property StartTime: TDateTime read FStartTime write SetStartTime;
property EndTime: TDateTime read FEndTime write SetEndTime;
end;

procedure Register;

implementation

procedure TDTCalc.SetStartTime(Value: TDateTime);
begin
FStartTime := Value;
Calculate;
end;

procedure TDTCalc.SetEndTime(Value: TDateTime);
begin
FEndTime := Value;
Calculate;
end;

procedure TDTCalc.Calculate;
var
e: Extended;
TempStr: String;

procedure Truncate(var Value: Int64);
begin
try
Value := Trunc(e);
except
Value := -1;
end;
end;

begin
e := MSecsPerDay * (FEndTime - FStartTime);
Truncate(FMSeconds);
TempStr := IntToStr(FMSeconds);
if TempStr[Length(TempStr)] = '9' then inc(FMSeconds);
e := e / 1000;
Truncate(FSeconds);
e := e / 60;
Truncate(FMinutes);
e := e / 60;
Truncate(FHours);
e := e / 24;
Truncate(FDays);
FMonths := Trunc((FEndTime - FStartTime) / 30.4375);
FYears := Trunc((FEndTime - FStartTime) / 365.25);
end;

procedure TDTCalc.SetNone; begin {} end;

procedure Register;
begin
RegisterComponents('UtilMind', [TDTCalc]);
end;

end.

冰封 (2002-05-30 0:50:00)
来自:叮叮当当, 时间:2002-5-29 23:15:00, ID:1131940
TO: xiao_ping
menxin的程序最后好像也有问题(计算天数的地方):
r3:=DayOf(Date2)-DayOf(Date1) +IfThen(DayOf(Date1)<=DayOf(Date2),0,DaysInMonth(StartOfTheMonth(Date2)-1));
假如
Date1=2000-01-30
Date2=2000-03-31

StartOfTheMonth(Date2)=2000-03-01
StartOfTheMonth(Date2)-1=2000-02-29 (TDataTime的整数部分就是天数,减1就等于天数减1)
DaysInMonth(StartOfTheMonth(Date2)-1)=29
DayOf(Date1)<=DayOf(Date2) 成立,因此 r3:=DayOf(Date2)-DayOf(Date1) +29=31-30+29=30 (天)
这是错误的,应该是“2个月零1天”。

其实,这程序基本上是可以的,就是你指出的地方有问题,修改的方法如下:
在他的程序最后部分加上
r2:= r2 + r3 div DaysInMonth(StartOfTheMonth(Date2)-1);
r3:= r3 mod DaysInMonth(StartOfTheMonth(Date2)-1);

叮叮当当 (2002-05-30 1:07:00)
To: hamsoft
你这段程序计算出来的和用HoursBetween、MinutesBetween、SecondsBetween算出来的一样。没法用。

冰封 (2002-05-30 1:16:00)
只要照我说那样改就成了,虽然我没试过程序,
不过从数学逻辑的角度上看,一定可以。

叮叮当当 (2002-05-30 1:23:00)
To: 冰封
我试了一下
Date1=2000-01-30
Date2=2000-03-31
是没问题了,可是我又随便设了一下
Date1=2002-05-30
Date2=2002-06-29
就不对了,返回只有“1天”了。
程序比较复杂,我就不分析了。

杜宝 (2002-05-30 1:31:00)
呵呵,晚上上来看到,大概做了一下:对秒数的处理还有点小问题,但可能是数据类型精度
的问题了,困了,不改了,你看着办吧。用D6:
uses
DateUtils;
...

function DeTwoDateTime(Const St,Et :TDateTime):String;
Const
Fmt = '相差 %d 年 %d 月 %d 日 %d 小时 %d 分 %d 秒';
var
Year,Month,Day:Integer;
Hour,Min,Se:Integer;
begin
Year := YearsBetween(et,st);//相差总年数

Month := MonthsBetween(et,st) mod 12;//相差月数(年后的零头)

Day := Trunc(Et - IncMonth(IncYear(St,Year),Month));//取相隔XX年YY月后的天数零头

//下面的东东有点奇怪,你可以注释以后用2002-1-31与2002-6-1试试就明白了。
if (Et - Day) < IncMonth(Et,-1) then //如果间隔天数超过一个月
begin
Month := Month + 1;
Day := Day mod Trunc(Et - IncMonth(Et,-1));
end;


Hour := HoursBetween(Et,St) mod 24 ;//相差总小时
Min := MinutesBetween(Et,St) mod 60 ; //相差分钟
Se := SecondsBetween(Et,st) mod 60 ; // 相差秒数

Result := Format(Fmt,[Year,Month,Day,Hour,Min,Se]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
t1,t2:TDateTime;
begin
T1:=StrToDateTime('2002-05-31 20:59:59');//如果两个都是整数时有问题,可能是
//Tdatatime类型数据无法准确表示一个小数的缘故。
//不是每个分数都能用一个小数精确表示,涉及分数小数之间的转换,所以精度可能有点问题
//你可以试一下,不影响太多的。
//你用19:00:00 与20:00:00试试就知道了,但17:00:00 与20:00:00是正确的。

T2:=StrToDateTime('2002-06-1 19:00:00');

ShowMessage(DeTwoDateTime(T1,T2));
end;

又想了一下:
对于时间(小时,分,秒等)的处理,应该以字符处理为主,这样就不会有格式的问题了。只是一个分解
字符串的过程,你自己试试吧。

只要是通过直接计算的方法,我想,可能都会存在我上面说的问题的。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

好,搞定,安心睡觉!

叮叮当当 (2002-05-30 7:54:00)
TO: 杜宝
谢谢你,但是你的程序在
Date1=2002-05-30
Date2=2003-05-30
会返回“0年11月30天”

憔悴 (2002-05-30 4:27:00)


microming (2002-05-30 8:34:00)
formatfloat(格式,date1-date2);

lch93005 (2002-05-30 8:37:00)
用DecodeDate函数试试,将日期分解开来

tqhuo (2002-05-30 8:46:00)
用函数daysbettween(),yearsbetween(),monthsbetween()

魔鬼大师 (2002-05-30 8:52:00)
用一个sql函数就行了

seucag (2002-05-30 9:22:00)
什么SQL函数?

jswqg (2002-05-30 9:25:00)
好像没有那么复杂吧
其实,TDatetime可以转换成TTimeStamp;
具体Ttimestamp啥意思,你可以看Delphi的帮助啦

返回秒数
function TForm1.GetDateTimeTo(AStart, AEnd: TDateTime): Real;
var
FStart,FEnd: TTimeStamp;
dd,tt : Real;
begin
FStart := DateTimeToTimeStamp(AStart);
FEnd := DateTimeToTimeStamp(AEnd);
dd := FEnd.Date-FStart.Date;(天数)
tt := (FEnd.Time-FStart.Time)/1000;(从00:00:00起秒数)
dd := dd*24*3600;
Result := dd+tt;
end;
具体应用,你自己参照这改就成了!


bianlx (2002-05-30 10:21:00)
YearsBetween
MonthsBetween
daysBetween
MinutesBetween
SecondsBetween
MilliSecondBetween
利用上述函数分别来进行计算,然后逐一减去上面得到的数值后再计算


杜宝 (2002-05-30 19:42:00)
呵呵,楼上说的TTimeStamp,不太明白的说,还请举例说明。

早晨心情好,重写了一个,应该比较好了,上面的例子都通过了,你再试试。
function De2DateTime(Const St,Et :TDateTime):String;
const
Fmt = '相差 %d 年 %d 月 %d 日 %d 小时 %d 分 %d 秒 %d 毫秒';
var
//以下变量,S开始的为开始时间,E开始的为结束时间。
SYear,EYear,
SMonth,EMonth,
SDay,EDay:Word;
SHour,EHour,
SMin,EMin,
SSec,ESec,
SMSec,EMSec:Word;

EDate:TDateTime;//起、至数据,只是传入参数不是Var的,做中间变量用。

DYear,DMonth,DDay,DHour,DMin,DSec,DMSec:Integer;//时差。
I:Integer;//中间变量,记录时差间隔。

//中间过程,初始变量。
procedure InitVars;
begin
DeCodeDate(EDate,EYear,EMonth,EDay);
DeCodeTime(EDate,EHour,EMin,ESec,EMSec);
end;
begin
if St > Et then //参数出错。
begin
Result := 'Error!';
Exit;
end;
//变量初始化。
// DYear:=0 ;DMonth:=0;DDay:=0;DHour:=0;DMin:=0;DSec:=0;DMSec:=0;
EDate := Et;
DeCodeDate(St,SYear,SMonth,SDay);
DeCodeTime(St,SHour,SMin,SSec,SMSec);

InitVars;
//进位的加减。从最低位开始!
//先来毫秒位:

DMSec := EMSec - SMSec;//取毫秒位差
if DMSec < 0 then //不足应该借位
begin
DMSec := 1000 + DMSec;
EDate := IncSecond(EDate,-1);//借位。
InitVars;//改变量。
end;
DSec := ESec - SSec ;//取秒位差
if DSec < 0 then
begin
DSec := 60 + DSec;
EDate := IncMinute(EDate,-1);
InitVars;
end;
DMin := EMin - SMin;//取分钟差
if DMin < 0 then
begin
DMin := 60 + DMin;
EDate := IncHour(EDate,-1);
InitVars;
end;

DHour := EHour - SHour;//取小时差
if DHour < 0 then
begin
DHour := 24 + DHour;
EDate := IncDay(EDate,-1);
InitVars;
end;
//**********************************************
//改:
DDay := EDay - SDay;//取天差,这里就复杂了!
if DDay < 0 then
begin
DDay := DaysInMonth(SDay) - SDay + EDay;//到月底,再加
EDate := IncMonth(EDate,-1);
InitVars;
end;
{ 原先的是错的
******************************************
DDay := EDay - SDay;//取天差,这里就复杂了!
if DDay < 0 then
begin
while DDay < 0 do
begin
i:= DaysBetween(EDate , IncMonth(EDate,-1));//取当月天数
DDay := i + DDay;
EDate :=IncMonth(EDate,-1);
end;
InitVars;
end;
***************************************
}
DMonth := EMonth - SMonth ;
if DMonth < 0 then
begin
DMonth := 12 + DMonth;
EDate := IncYear(EDate,-1);
InitVars;
end;

DYear := EYear - SYear;
if DYear < 0 then
begin
Result := 'Error!';
Exit;
end;
//结果!
Result := Format(Fmt,[DYear,DMonth,DDay,DHour,DMin,DSec,DMSec]);

end;

procedure TForm1.Button1Click(Sender: TObject);
var
t1,t2:TDateTime;
begin

T1:=StrToDateTime('2002-01-31 20:59:59.540');

T2:=StrToDateTime('2002-2-11 19:00:00.001');

ShowMessage(De2DateTime(T1,T2));

end;




real_clq (2002-05-30 11:07:00)
不会吧,这么简单的问题说得....
var
t1,t2:TDateTime;
...
t1:=now;
sleep(100);
t2:=now;
showmessage(formatdatetime(''<-这里写上自己要的格式,t1-t2));
..
///////////////////
记住TDateTime之间相减的结果仍然是TDateTime就行了,怎么转换就由你了。

萧月禾 (2002-05-30 14:28:00)
ShowMessage(formatdatetime('yyyy-mm-dd hh:ss:nn:zzz', T2-T1-693594));

返回字符串: 0001-01-02 18:48:28:000
通过分析字符串的“-”“:”得到你要的各个值,再转为整数
(则把当中0开头的值的0去之)

萧月禾 (2002-05-30 14:37:00)
忘了说明,分析的结果中,日期的各部分的值均减1[:)]

杜宝 (2002-05-30 15:07:00)
呵呵,萧兄高明,能否讲讲693594的含义,谢谢。

萧兄的程序好象还有点小问题,对跨月处理、闰年处理都有点问题:
小弟的试验:
procedure TForm1.Button1Click(Sender: TObject);
var
t1,t2:TDateTime;
i:Integer;
s,s1:String;
begin

T1:=StrToDateTime('2003-12-01 12:30:00');

for i := 0 to 370 do
begin
T2 := T1 + i;
s:=formatdatetime('yyyy-mm-dd hh:ss:nn:zzz', T2-T1-693595);
s1:=De2DateTime(T1,T2);
memo1.Lines.Add(IntToStr(i)+' : '+DateToStr(t2)+' '+s+' '+s1);
end;
end;
起始:2001-01-29 12:30:00
0 : 2001-1-29 0000-00-00 00:00:00:000 相差 0 年 0 月 0 日 0 小时 0 分 0 秒 0 毫秒 //不用减
...
59 : 2001-3-29 0001-02-27 00:00:00:000 相差 0 年 2 月 0 日 0 小时 0 分 0 秒 0 毫秒 //不整月时 应该进位。
如果是闰年:2004-01-29 12:30:00,则:
31 : 2004-2-29 0001-01-30 00:00:00:000 相差 0 年 1 月 0 日 0 小时 0 分 0 秒 0 毫秒 //整月,进位
60 : 2004-3-29 0001-02-28 00:00:00:000 相差 0 年 2 月 0 日 0 小时 0 分 0 秒 0 毫秒 //整月,进位
如果跨年时:2001-12-1开始
0 : 2001-12-1 0000-00-00 00:00:00:000 相差 0 年 0 月 0 日 0 小时 0 分 0 秒 0 毫秒 //正确
1 : 2001-12-2 0000-00-00 00:00:00:000 相差 0 年 0 月 1 日 0 小时 0 分 0 秒 0 毫秒 //不对
如果时差超过一年时:以2001-12-1开始:
365 : 2002-12-1 0001-12-30 00:00:00:000 相差 1 年 0 月 0 日 0 小时 0 分 0 秒 0 毫秒
366 : 2002-12-2 0001-12-31 00:00:00:000 相差 1 年 0 月 1 日 0 小时 0 分 0 秒 0 毫秒
也有问题。
还请再试试。





萧月禾 (2002-05-30 15:24:00)
to 杜宝:
刚刚我验证了一下,那方法对日期部分的处理是可以的,不管跨月处理、闰年处理都是
可以的,但。。。对时间部分处理是错误的,和formatdatetime函数处理结果有关,
搞了半天还是解决不了,看来还是得放弃用formatdatetime的方法了[:(]

萧月禾 (2002-05-30 15:31:00)
写成这个过程,日期部分返回结果试了几下,应该是正确的
但时间部分不对,搞不懂 [:(]
procedure GetDateTimeDiff(const D1, D2: TDateTime; var AYear,
AMonth, ADay, AHour, AMin, ASec, AMSec: Word);
var
sDateDiff: string;
begin
//
sDateDiff := formatdatetime('yyyy-mm-dd hh:ss:nn:zzz', D1 - D2 -693594 + 1 );

AYear := StrToInt(Copy(sDateDiff,1,4)) - 1;
AMonth := StrToInt(Copy(sDateDiff,6,2)) - 1;
ADay := StrToInt(Copy(sDateDiff,9,2)) - 1;
AHour := StrToInt(Copy(sDateDiff,11,2));
AMin := StrToInt(Copy(sDateDiff,15,2));
ASec := StrToInt(Copy(sDateDiff,18,2));
AMSec := StrToInt(Copy(sDateDiff,21,3));
end;


萧月禾 (2002-05-30 15:47:00)
有个地方写错了,应该从12开始,不是11
AHour := StrToInt(Copy(sDateDiff,12,2));
这样的话,一直到小时部分的差值是正常的
但,毫秒的差值不起作用,这也罢了
最搞不懂的是,分和秒的差值居然是正好相反的
即分差的值出现在秒差的位置,秒差的值出现在分差的位置
顺序似乎又没错。。。。真搞不懂

萧月禾 (2002-05-30 15:57:00)
原来是formatdatetime里面的格式写错了(顺手拷上面某仁兄的)
现在可以了,但对毫秒还是不起作用
procedure GetDateTimeDiff(const D1, D2: TDateTime; var AYear,
AMonth, ADay, AHour, AMin, ASec, AMSec: Word);
var
sDateDiff: string;
begin
//
sDateDiff := formatdatetime('yyyy-mm-dd hh:mm:ss:nnn', D1 - D2 -693594 + 1 );

AYear := StrToInt(Copy(sDateDiff,1,4)) - 1;
AMonth := StrToInt(Copy(sDateDiff,6,2)) - 1;
ADay := StrToInt(Copy(sDateDiff,9,2)) - 1;
AHour := StrToInt(Copy(sDateDiff,12,2));
AMin := StrToInt(Copy(sDateDiff,15,2));
ASec := StrToInt(Copy(sDateDiff,18,2));
AMSec := StrToInt(Copy(sDateDiff,21,3));
end;


杜宝 (2002-05-30 16:12:00)
呵呵,小弟以为,萧兄的方法,关键是那个常数定位的准确性。

但有个问题是:日期是有一定连续性的,是线性的;但读法就不一定,它是非线性的
因此如果用一个常数来处理的话(等差数列,是线性的),我想是有问题的。
还有就是小数的问题,如果用常数的话,涉及到与整数位的进位,这样就有问题了。

萧兄的第一次修改程序小弟测试还是有问题:
比如:
2001.12.1与 2002-10-31 0 小时 0 分 0 秒
萧兄的是:
0 年 11 月 0 日
小弟的是:
0 年 10 月 30 日 0 小时 0 分 0 秒 0 毫秒,

第二次的formatDateTime修改后,小数位先不论:

2001.12.1 0:0:0.000

364 : 2002-11-30
相差 0 年 11 月 30 日 0 小时 0 分 0 秒 0 毫秒 //萧兄
相差 0 年 11 月 29 日 0 小时 0 分 0 秒 0 毫秒 //小弟

加上小数位后差异更大。

想请萧兄把测试程序贴出来。



萧月禾 (2002-05-30 16:27:00)
这是我的测试程序,通过修改edit中的日期格式的字符串的值来进行测试
不是很全面,不过我试了许多例子确实没发现错误的结果
另外,至于那个常数,你用0减去它,再转为日期型,看看是什么[:)]
procedure TForm1.rbbtnRzBitBtn1Click(Sender: TObject);
var
AYear, AMonth, ADay, AHour, AMin, ASec, AMSec: Word;
D1, D2: TDateTime;
begin
D1 := StrToDateTime(edit2.text);//2002-01-01 00:00:00:000 格式
D2 := StrToDateTime(edit3.text);//2002-01-01 00:00:00:000

GetDateTimeDiff(D1, D2, AYear, AMonth, ADay, AHour, AMin, ASec, AMSec);

edit1.text := inttostr(AYear)+ '年'+ inttostr(AMonth)+'月'+ inttostr(ADay)+'日'+
inttostr(AHour)+'小时'+ inttostr(AMin)+'分'+ inttostr(ASec)+'秒';

end;


杜宝 (2002-05-30 16:41:00)
萧兄的东东,小弟把它改了一下:
function GetDateTimeDiff(const D1, D2: TDateTime):String;
const
Fmt = '相差 %d 年 %d 月 %d 日 %d 小时 %d 分 %d 秒 %d 毫秒';

var
sDateDiff: string;
AYear, AMonth, ADay, AHour, AMin, ASec, AMSec: Word;
begin
//

sDateDiff := formatdatetime('yyyy-mm-dd hh:mm:ss:nnn', D2 - D1 -693594 +1 );

AYear := StrToInt(Copy(sDateDiff,1,4)) - 1;
AMonth := StrToInt(Copy(sDateDiff,6,2)) - 1;
ADay := StrToInt(Copy(sDateDiff,9,2)) - 1;
AHour := StrToInt(Copy(sDateDiff,12,2));
AMin := StrToInt(Copy(sDateDiff,15,2));
ASec := StrToInt(Copy(sDateDiff,18,2));
AMSec := StrToInt(Copy(sDateDiff,21,3));
Result :=inttostr(AYear)+ '年'+ inttostr(AMonth)+'月'+ inttostr(ADay)+'日'+
inttostr(AHour)+'小时'+ inttostr(AMin)+'分'+ inttostr(ASec)+'秒';

// Result := Format(Fmt,[AYear,AMonth,ADay,AHour,AMin,ASec,AMSec]);
end;

我的测试代码:
procedure TForm1.Button1Click(Sender: TObject);
var
t1,t2:TDateTime;
i:Integer;
s,s1:String;
begin

T1:=StrToDateTime('2003-12-01 0:0:0.000');

for i := 0 to 370 do
begin
T2 := T1 + i*1{.01}; //测试小数不注释。
s:=GetDateTimeDiff(t1,t2);
s1:=De2DateTime(T1,T2);
memo1.Lines.Add(IntToStr(i)+' : '+DateTimeToStr(t2)+' '+s+' '+s1);
end;
end;

在小弟的机器上还是有问题:
365 : 2004-11-30 1年0月0日0小时0分0秒 相差 0 年 11 月 29 日 0 小时 0 分 0 秒 0 毫秒
366 : 2004-12-1 1年0月1日0小时0分0秒 相差 1 年 0 月 0 日 0 小时 0 分 0 秒 0 毫秒
367 : 2004-12-2 1年0月2日0小时0分0秒 相差 1 年 0 月 1 日 0 小时 0 分 0 秒 0 毫秒

我的想法,萧兄不应该把这个常数设定为整数,可能它是一个小数的说。
我想这和数据类型的二进制表示精度有关。
但现在我对这种方法,不太看好,原因就是上面我说的。^_^

萧月禾 (2002-05-30 16:55:00)
杜大侠果然是个严谨的人[:)]
不过那个常数是经过换算得来的,的确是个整数,加上小数反而不正确了
其实我只想尽量用最简单的方法去解决问题
我再测试一下,如果真的不行再考虑放弃罢

zhihuali (2002-05-30 18:29:00)
个人认为时间相差的年跟月很难说,倒不如说过了多少天来的准确;所以日期部分自己去
改良一下(不知道我的结果正确不正确,反正我没有测试。呵呵!)。
function GetDateTimeDiff(const D1, D2: TDateTime): String;
const
Fmt = '现已经正常运行 %d 年 %d 月 %d 日 %d 小时 %d 分 %d 秒';
var
DT : TDateTime;
D : Integer;
T : TTime;
Year, Month, Day : Word;
Hour, Min, Sec, mSec, mSec0, mSec1 : Word;
begin
DT := D2 - D1;
D := Trunc(DT);
T := DT - D;
if D > 0 then
begin
Year := D div 365;
Month := (D mod 365) div 30;
Day := (D mod 365) mod 30;
end
else
begin
Year := 0;
Month := 0;
Day := 0;
end;
DecodeTime(D2, Hour, Min, Sec, mSec0);
DecodeTime(D1, Hour, Min, Sec, mSec1);
if mSec1 > mSec0 then
T := T + EncodeTime(0, 0, 1, 0);
DecodeTime(T, Hour, Min, Sec, mSec);
Result := Format(Fmt, [Year, Month, Day, Hour, Min, Sec]);
end;


南宫吹云 (2002-05-30 19:33:00)
各位的讨论好精辟呀,收藏。

杜宝 (2002-05-30 19:39:00)
呵呵,首先,我的程序有问题,就是对于1.31 到 3.1之后的日期取数有问题:
2001.1.31 到 2001.3.1 相隔应该是1个月零1天,但我的上面的程序是30天,
这是不对的。
原因是对天数的取值不对,因为天数与月分的关系不是单纯的进位的关系,所
以不能直接借位取。改成:
...
DDay := EDay - SDay;//取天差,这里就复杂了!
if DDay < 0 then
begin
DDay := DaysInMonth(SDay) - SDay + EDay;//到月底,再加
EDate := IncMonth(EDate,-1);
InitVars;
end;
...
就OK 了。

萧兄的说常数的问题,是我的概念有问题,萧兄是对的。我试了一下,萧兄的方法对于秒
位的处理都是正确的。微秒的方法应该是精度的问题了。


黎兄的程序对于时间的处理是对的,但对日期的处理还是有问题。除了我说2月计算以外
对于跨月的处理有问题例如:
从2004.1.31到 2005-1-25
现已经正常运行 0 年 12 月 0 日 0 小时 0 分 0 秒
相差 0 年 11 月 25 日 0 小时 0 分 0 秒 0 毫秒
出现了12个月的情况。这不是进位的问题是计算不对。


zhihuali (2002-05-30 19:52:00)
To : 杜宝
>> 黎兄的程序对于时间的处理是对的,但对日期的处理还是有问题。
呵呵,我可能没有说清楚我的意思;我说了,时间相差的年跟月很难说,
倒不如说过了多少天来的准确(所以我算了天数后随便处理年月日的关系);
我在日期部分的处理只是起个抛砖引玉的作用,并不是有问题。
所以我说明了自己去改良后再用啊。什么都说的清清楚楚的就没有意思了。

杜宝 (2002-05-30 20:04:00)
呵呵,黎兄所说的道理,小弟是极为认同的。本贴的问题其实是个惯用语的问题。
惯用语确实不如时间差来得精确。但楼主就是这么要求的,小弟也没办法^_^

其实我与萧兄讨论的重点, 是在于能不能用简单的增减一个常量来读出这个惯用语
现在看来,常数的方法可能有问题,2月份的处理这关就过不了。所以我现在怀疑黎
兄的东东不能能改良得出来。

就事论事,黎兄见笑了。





zhihuali (2002-05-30 20:05:00)
如果今天晚上睡觉时还没有结束就抽空写完整一点。希望杜兄和萧兄写一个
简单有效的过程函数来解决,呵呵。我觉得这个问题虽然不难,但要有效并简单
解决就。。。,不知道大家怎么看?


叮叮当当 (2002-05-30 20:30:00)
To: 杜宝
你早上重写的程序好像没问题了,我测试了几个数据,很完美!:)[:)]
我正在消化吸收,如果没有意外的话,这个帖子就快结了。[8D]

萧月禾 (2002-05-30 20:51:00)
凭良心说,我那个函数有什么问题吗?
我真的测不出不妥的地方呀???[:(]

萧月禾 (2002-05-30 21:08:00)
哦,我明白我错在什么地方了,多谢杜兄提点
你才是正确的[:)]

叮叮当当 (2002-05-30 21:48:00)
TO: 萧月禾
我也一直想寻求一种简单的解决这个问题的办法,就像你的程序,可惜事与愿违。

TO: 杜宝
我把你的代码整理了一下,附上测试程序:

新建一个Application,在窗体上放置一个TEdit和一个TTimer,双击Timer1让IDE生成OnTimer事件,然后粘贴下面整段代码,按F9运行。
代码:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

procedure DateTimeDiff(St, Et: TDateTime; out Y, M, D, H, N, S, MS: Word);

var
  Form1: TForm1;

implementation

uses DateUtils;

var
  BeginTime: TDateTime;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  BeginTime := Now;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Y, M, D, H, N, S, MS: Word;
begin
  DateTimeDiff(BeginTime, Now, Y, M, D, H, N, S, MS);
  Edit1.Text := Format('已运行 %d 年 %d 月 %d 日 %d 小时 %d 分 %d 秒 %d 毫秒',
    [Y, M, D, H, N, S, MS]);
end;

procedure DateTimeDiff(St, Et: TDateTime; out Y, M, D, H, N, S, MS: Word);
var
  SYear, SMonth, SDay, SHour, SMin, SSec, SMSec: Word;      // 开始时间
  EYear, EMonth, EDay, EHour, EMin, ESec, EMSec: Word;      // 结束时间
  DYear, DMonth, DDay, DHour, DMin, DSec, DMSec: Integer;   // 时差
  EDate: TDateTime;                 // 中间变量
  i: Integer;                       // 中间变量,记录时差间隔。

  procedure InitVars;
  begin
    DecodeDateTime(EDate, EYear, EMonth, EDay, EHour, EMin, ESec, EMSec);
  end;
begin
  if St > Et then                   // 参数出错
  begin
    EDate := St;                    // 交换起止时间
    St := Et;
    Et := EDate;
  end;

  // 变量初始化。
  DecodeDateTime(St, SYear, SMonth, SDay, SHour, SMin, SSec, SMSec);
  EDate := Et;
  InitVars;

  // 进位的加减,不足则借位。
  // 从最低位开始,先来毫秒位:
  DMSec := EMSec - SMSec;           // 取毫秒位差
  if DMSec < 0 then
  begin
    DMSec := 1000 + DMSec;
    EDate := IncSecond(EDate, -1);  // 借位
    InitVars;                       // 改变量
  end;
  DSec := ESec - SSec;              // 取秒位差
  if DSec < 0 then
  begin
    DSec := 60 + DSec;
    EDate := IncMinute(EDate, -1);
    InitVars;
  end;
  DMin := EMin - SMin;              // 取分钟差
  if DMin < 0 then
  begin
    DMin := 60 + DMin;
    EDate := IncHour(EDate, -1);
    InitVars;
  end;
  DHour := EHour - SHour;           // 取小时差
  if DHour < 0 then
  begin
    DHour := 24 + DHour;
    EDate := IncDay(EDate, -1);
    InitVars;
  end;

  DDay := EDay - SDay;              // 取天差,这里就复杂了!
  if DDay < 0 then
  begin
    DDay := DaysInMonth(SDay) - SDay + EDay;  // 到月底再加
    EDate := IncMonth(EDate, -1);
    InitVars;
  end;
  DMonth := EMonth - SMonth ;       // 取月差
  if DMonth < 0 then
  begin
    DMonth := 12 + DMonth;
    EDate := IncYear(EDate, -1);
    InitVars;
  end;
  DYear := EYear - SYear;           // 取年差
  Assert(DYear >= 0, '应该不可能小于0!');

  Y := DYear; M := DMonth; D := DDay;
  H := DHour; N := DMin; S := DSec; MS := DMSec;
end;

end.
你的程序才是真正符合我要求的。
向你的严谨态度致敬!

hjb_dydd (2002-05-30 22:20:00)
好象不用这么烦吧!

好象SQL Server里有专门的函数的嘛!好象就叫DATEDIFF( )的!只要两个参数就可以了!

冰封 (2002-05-31 0:53:00)
“来自:叮叮当当, 时间:2002-5-29 23:15:00, ID:1131940
TO: xiao_ping
menxin的程序最后好像也有问题(计算天数的地方):
r3:=DayOf(Date2)-DayOf(Date1) +IfThen(DayOf(Date1)<=DayOf(Date2),0,DaysInMonth(StartOfTheMonth(Date2)-1));
假如
Date1=2000-01-30
Date2=2000-03-31

StartOfTheMonth(Date2)=2000-03-01
StartOfTheMonth(Date2)-1=2000-02-29 (TDataTime的整数部分就是天数,减1就等于天数减1)
DaysInMonth(StartOfTheMonth(Date2)-1)=29
DayOf(Date1)<=DayOf(Date2) 成立,因此 r3:=DayOf(Date2)-DayOf(Date1) +29=31-30+29=30 (天)
这是错误的,应该是“2个月零1天”。


to 叮叮当当:
你得到你要的答案了吗?
我测试了一下menxin的程序,发现你之前分析的结果有错。
我运行得到的结果是2个月零1天没错呀。

另外我觉得,如果月份不以固定的天数计算,会出现让人理解上的错误,
假如 Date1=2000-01-30 Date2=2000-03-29,这样应该是过了1个月28天或者1个月29天或者1个月30天?

冰封 (2002-05-31 0:57:00)
不过menxin的程序的确有他的错误。

我认为还是用天表示就好,否则容易让人误解。

叮叮当当 (2002-05-31 1:15:00)
TO: 冰封
>另外我觉得,如果月份不以固定的天数计算,会出现让人理解上的错误,
>假如 Date1=2000-01-30 Date2=2000-03-29,这样应该是过了1个月28天或者1个月29天或者1个月30天?
也有点道理,差点连我自己也不知道结果应该是什么了,不过我用杜宝兄的程序试了一下,返回的是“1月30日”。我想了一下,这也很好解释呀。那个“1月”是指2月份整月(29天),30天是指3月份的1号~29号+1月份的31号。[:D]我这个也有道理的啊:D

叮叮当当 (2002-05-31 1:26:00)
谢谢大家!给分了。

杜宝 (2002-05-31 1:44:00)
很不爽!!!!!睡前忍不住再说两句,感觉这个贴里面说的人多,做的人少。
这种程序,我想只要多测试就能看出效果。很多方法,其实只要充分测试一下,
就可以看出好坏来了。我不知道大家测试的数据有多少,我自己测试的时候,
基本都用1000个组数据做循环,再加上小数位的,具体可以看我上面的贴子。

冰封朋友说menxin的方法是对的,好,那我们来做个测试:
新建一个工程,加一个Button 一个 Memo,把我的程序:
De2DateTime贴上,
begin
...
//结果!
Result := Format('两个日期相差%d年%d个月%d天',[Dyear,DMonth,DDay]); //这里改一下,统一输出。
end;
再把menxin兄方法改一下:
function D2(st,et:TDateTime) :String;
var
Date1,Date2:TDate;
r1,r2,r3:integer;
begin
Date1:=Min(st,et);
Date2:=Max(st,et);
r1:=YearsBetween(Date1,Date2);
r2:=MonthsBetween(Date1,Date2)-r1*12;
r3:=DayOf(Date2)-DayOf(Date1) +IfThen(DayOf(Date1)<=DayOf(Date2),0,DaysInMonth(StartOfTheMonth(Date2)-1));
r2:= r2 + r3 div DaysInMonth(StartOfTheMonth(Date2)-1);
r3:= r3 mod DaysInMonth(StartOfTheMonth(Date2)-1);
Result := Format('两个日期相差%d年%d个月%d天',[r1,r2,r3]);
end;
按冰封兄的修改方法改后的版本:
function D1(st,et:TDateTime) :String;
var
Date1,Date2:TDate;
r1,r2,r3:integer;
begin
Date1:=Min(st,et);
Date2:=Max(st,et);
r1:=YearsBetween(Date1,Date2);
r2:=MonthsBetween(Date1,Date2)-r1*12; //按冰封兄的贴子修改
r3:=DayOf(Date2)-DayOf(Date1) +IfThen(DayOf(Date1)<=DayOf(Date2),0,DaysInMonth(StartOfTheMonth(Date2)-1));
Result := Format('两个日期相差%d年%d个月%d天',[r1,r2,r3]);
end;
一起来做个测试:
先来menxin兄的:
procedure TForm1.Button1Click(Sender: TObject);
var
t1,t2:TDateTime;
i:Integer;
s,s1:String;
begin

T1:=StrToDateTime('2003-12-01'); //起始日期

for i := 0 to 370 do //循环测试370天,比对370天内的不同
begin
T2 := T1 + i*1; //测试小数不注释。
s:=D2(t1,t2);
s1:=De2DateTime(T1,T2);
if s <> s1 then //两种方法不同时显示!
memo1.Lines.Add(DateTimeToStr(t1)+' : '+DateTimeToStr(t2)+' '+s+' '+s1);
end;
end;
如果:且不说冰封兄上面说的语义上的区别:
2003-12-1 : 2003-12-31 两个日期相差0年1个月0天 两个日期相差0年0个月30天 //这里
2003-12-1 : 2004-1-31 两个日期相差0年2个月30天 两个日期相差0年1个月30天
2003-12-1 : 2004-3-1 两个日期相差0年2个月0天 两个日期相差0年3个月0天 //这里
2003-12-1 : 2004-3-30 两个日期相差0年4个月0天 两个日期相差0年3个月29天
2003-12-1 : 2004-3-31 两个日期相差0年4个月1天 两个日期相差0年3个月30天
2003-12-1 : 2004-5-1 两个日期相差0年4个月0天 两个日期相差0年5个月0天
2003-12-1 : 2004-5-31 两个日期相差0年6个月0天 两个日期相差0年5个月30天 // 这里
2003-12-1 : 2004-7-1 两个日期相差0年6个月0天 两个日期相差0年7个月0天 //这里
2003-12-1 : 2004-7-31 两个日期相差0年8个月0天 两个日期相差0年7个月30天
2003-12-1 : 2004-8-31 两个日期相差0年9个月30天 两个日期相差0年8个月30天 //这里
2003-12-1 : 2004-10-31 两个日期相差0年12个月0天 两个日期相差0年10个月30天 //这里
谁对谁错应该很明显了吧???

好,再来冰封兄的版本
procedure TForm1.Button1Click(Sender: TObject);
var
t1,t2:TDateTime;
i:Integer;
s,s1:String;
begin

T1:=StrToDateTime('2003-12-01');

for i := 0 to 370 do
begin
T2 := T1 + i; //测试小数不注释。
s:=D1(t1,t2);
s1:=De2DateTime(T1,T2);
if s <> s1 then
memo1.Lines.Add(DateTimeToStr(t1)+' : '+DateTimeToStr(t2)+' '+s+' '+s1);
end;
end;
结果:
2003-12-1 : 2004-1-31 两个日期相差0年2个月30天 两个日期相差0年1个月30天
2003-12-1 : 2004-3-1 两个日期相差0年2个月0天 两个日期相差0年3个月0天
2003-12-1 : 2004-5-1 两个日期相差0年4个月0天 两个日期相差0年5个月0天
2003-12-1 : 2004-7-1 两个日期相差0年6个月0天 两个日期相差0年7个月0天
2003-12-1 : 2004-8-31 两个日期相差0年9个月30天 两个日期相差0年8个月30天
2003-12-1 : 2004-10-31 两个日期相差0年11个月30天 两个日期相差0年10个月30天

不用我说了吧????





叮叮当当 (2002-05-31 2:01:00)
TO: 杜宝
SORRY,分是少了点。
我们可以交个朋友么?MSN:pschen@21cn.com,QQ:990080。

冰封 (2002-05-31 23:31:00)
to 杜宝:
>>>>只要照我说那样改就成了,虽然我没试过程序,不过从数学逻辑的角度上看,一定可以。
>>这又是什么态度?难道我说“感觉这个贴里面说的人多,做的人少。”有问题吗?
这句我是对叮当得出的结果,给想了个修改的方法,而对叮当当时指的那个错误,那种修改方式是可行的,因为叮当指出一个错误,当时我误以为menxin的程序就那个错误。
就这句上我承认我回答得太片面了。

>>>>我测试了一下menxin的程序,发现你之前分析的结果有错。
>>是什么结果有错,拜托你说清楚好不好?是menxin的还是你的?
是什么结果错,我有在那个贴子之前贴出,也说了我的测试结果。你要断章取义我也没办法。至于我的还是menxin的,那没有提的必要,我的本意就是只对menxin做补充,而menxin本身程序有错,我的当然也是错的。

至于你喜欢针对我,你喜欢自我称赞,那是你的自由。
我想我作的解释很明白了,如果叮叮当当也认为我有错,那我向叮当说声“对不起”。
至于你爱怎么说你说吧,我不再与你做无谓的争执。


杜宝 (2002-05-31 23:02:00)
呵呵,冰封,就是针对你,就是自我称赞,怎么了?
象你说的,
>>本来论坛就是畅所欲言的地方:
那好,我测试了一下menxin的程序,再测试你修改后的程序,证明它们是错的。
(当然,我知道这并不能证明我的程序就一定是正确的。)有何不可?

>>我测试了一下menxin的程序,发现你之前分析的结果有错。
是什么结果有错,拜托你说清楚好不好?是menxin的还是你的?

>>只要照我说那样改就成了,虽然我没试过程序,不过从数学逻辑的角度上看,一定可以。
这又是什么态度?难道我说“感觉这个贴里面说的人多,做的人少。”有问题吗?







杜宝 (2002-06-01 3:11:00)
KAO,少来! 说不过了就把自己的原贴改掉,要不要我提醒你:

这本来是个技术问题,是谁把它转成对我人品的讨论的?

你说我断章取意,干嘛不说你自己断章取意???

是谁自己不做测试,还找弱智的借口来搪塞?
KAO ,手伤了??? 你上网不用手,发贴不用手???

我测试你的代码,指出你的错误,就说我针对你,你以为你是谁啊?

KAO , 你TMD小人一个!!!

萧月禾 (2002-06-01 10:00:00)
看到邮件才知道这里发生的事
只是讨论个技术问题
别伤和气呀。。。。。。。。

原野飞侠 (2003-04-06 14:14:00)
sc


hamsoft-2,linsb-2,mlzhou-2,Pearl.-2,qdyoung-2,xiao_ping-2,zhihuali-2,冰封-6,杜宝-70,萧月禾-8,雪鹰-2,的回答最终被接受。
 
var Year,Month,Day,Hour,Minute,Second,MilliSecond:Word;
MyDate,MyTime,MyDateTime:TDateTime;

数字转日期 MyDate:=EncodeDate(Year,Month,Day);
数字转时间 MyTime:=EncodeTime(Hour,Min,0,0);
MyDateTime:=EncodeDateTime(Year,Month,Day,Hour,Minute,Second,MilliSecond);
分离时分秒 DecodeTime(Time,Hour,Minute,Second,MilliSecond);
分离年月日 DecodeDate(Date,Year,Month,Day);

字符转日期时间 StrToDateTime('2002-12-30 10:30:00 am')
日期转字符 DateToStr(Date)

求两时间的天数、小时、分
天=Trunc(DateTime2-DateTime1);
时=HourOf(DateTime2-DateTime1);
分=MinuteOf(DateTime2-DateTime1);
两时间的小时:HoursBetween(Now, Old_DateTime);
两时间的分钟:MinutesBetween(Now, Old_DateTime);
两时间的毫秒: var OldTime:DWORD;
OldTime:=GetTickCount;
GetTickCount-OldTime;

时间加减
减少分钟 MyTime:=IncMinute(MyTime,-5);
增加天数 MyDate:=IncDay(MyDate,1);
增加月份 MyDate:=IncMonth(MyDate,1);

设置日期显示格式
DateSeparator:='-';
ShortDateFormat:='yyyy-mm-dd';
LongDateFormat:='yyyy-mm-dd';

设置系统时间
Var
MyTime:TSystemTime;
Begin
With MyTime do
Begin
Wyear:=2002;
Wmonth:=2;
Wday:=28;
Whour:=12;
Wminute:=30;
Wsecond:=10;
end;
SetLocalTime(MyTime);
end;

获取星期几
case DayOfWeek(Date) of
1:Week:=' 星期日';
2:Week:=' 星期一';
3:Week:=' 星期二';
4:Week:=' 星期三';
5:Week:=' 星期四';
6:Week:=' 星期五';
7:Week:=' 星期六';
end;
 
后退
顶部