線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4892
推到 Plurk!
推到 Facebook!

不解:日期時間的相減

尚未結案
chuanchuan
一般會員


發表:11
回覆:15
積分:5
註冊:2004-05-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-06-07 17:02:30 IP:163.29.xxx.xxx 未訂閱
tdatetime日期時間型直接相減,所得值好像是(日)數; 要換成小時,*24 應該沒錯吧,可是實作卻錯了 2004/06/08 12:00 減 2004/06/07 12:00 =0.999998.... 因此*24再取整數(捨去小數點),==> 23 有誰能解釋一下~謝謝~~ 小弟想不出解決之道,土法加上 0.00001 先能用再說~~ 有解決之道嗎?
l630521
資深會員


發表:15
回覆:349
積分:372
註冊:2003-02-17

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-06-07 17:08:58 IP:210.66.xxx.xxx 未訂閱
function YearsBetween(const ANow, AThen: TDateTime): Integer; function MonthsBetween(const ANow, AThen: TDateTime): Integer; function WeeksBetween(const ANow, AThen: TDateTime): Integer; function DaysBetween(const ANow, AThen: TDateTime): Integer; function HoursBetween(const ANow, AThen: TDateTime): Int64; function MinutesBetween(const ANow, AThen: TDateTime): Int64; function SecondsBetween(const ANow, AThen: TDateTime): Int64; function MilliSecondsBetween(const ANow, AThen: TDateTime): Int64; 如果你要算小時,請用HoursBetween... Ian
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-06-07 22:06:41 IP:61.229.xxx.xxx 未訂閱
剛好今天有用到HoursBetwee函數,順便提一下心得,發現這個函數會有bug,當傳入的兩個日期剛好跨一天時,會回傳錯誤的小時數目,如'093/06/06 21:30'與'093/06/07 22:30'時,回傳的竟是24,應該是25才是.    所以,最後乾脆自己寫,將時間轉以DateTimeToTimeStamp函數轉成TTimeStamp後,再去做自己要的計算.    底下是TTimeStamp的說明:
type       TTimeStamp = record
    Time: Integer;      { Number of milliseconds since midnight }
    Date: Integer;      { One plus number of days since 1/1/0001 }      end;
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-06-07 23:19:41 IP:211.20.xxx.xxx 未訂閱
chuanchuan 你好
我用以下程式不會有你說的問題
procedure TForm1.BitBtn2Click(Sender: TObject);
Var
  Str : String ;
  i, j : Integer;
  D1,D2 : TDateTime ;
begin
  D2 := strToDateTime('2004/06/08 12:00');
  D1 := strToDateTime('2004/06/07 12:00');
  // D1 := strToDateTime('2004/06/07 12:00:01');
  Label1.Caption := FloatToStr(D2-D1); // ====> 1
  Label2.Caption := IntToStr(Trunc((D2-D1)*24));// ====> 24
  Label3.Caption := IntToStr(HoursBetween(D1,D2));// ==== > 24
end;
但如上紅色部份就會得到你所述的答案 23 了,因為有了1秒的誤差所以日數為0.999998...是正常的。
引言: 小弟想不出解決之道,土法加上 0.00001 先能用再說~~
萬一兩個時間差不是1秒呢?加上0.00001還是不够,我覺得應該要有個容許誤差才對,最常用的就是四捨五入法 Label2.Caption := IntToStr(Trunc((D2-D1)*24 0.5));// 四捨五入====> 24
chuanchuan
一般會員


發表:11
回覆:15
積分:5
註冊:2004-05-18

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-06-15 10:36:40 IP:163.29.xxx.xxx 未訂閱
感謝大家~~ (d2-d1)*24 是小時數,因此不能四捨五入,因為算法是: 如果加班不滿一小時就不算,5.6小時還是算5小時, 而d2-d1是日數,我+0.000001再*24是因為,二時間差為 5小時59分時(使用者輸入精確度只到[分]), 即使加上0.00001也不會變成6小時,因此我才如此用 當然,這不是正統的方式.      D2 := strToDateTime('2004/06/08 12:00');   D1 := strToDateTime('2004/06/07 12:00');   Label1.Caption := FloatToStr(D2-D1); // ====> 1   Label2.Caption := IntToStr(Trunc((D2-D1)*24));// ====> 24   以上是對的,但是請試   D2 := strToDateTime('2004/06/08 13:00');   D1 := strToDateTime('2004/06/07 12:00');   Label2.Caption := IntToStr(Trunc((D2-D1)*24));// ====> 24   多了一小時,但結果還是24 所以問題在此      至於HoursBetween 不讓我用,為何?搜尋HoursBetween也找不到任何資料   不會吧 ~~~   < >< >
l630521
資深會員


發表:15
回覆:349
積分:372
註冊:2003-02-17

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-06-15 11:51:56 IP:210.66.xxx.xxx 未訂閱
你有沒有 uses DateUtils; Ian
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-06-15 12:01:31 IP:203.204.xxx.xxx 未訂閱
chuanchuan 你好
  四捨五入不行改為58捨59入,總之還是有容許誤差(1分鐘的誤差)    Var
  D1,D2 : TDateTime ;
  Dist : Double;
begin
  Dist := 1/(24*60) ;   // 誤差為1分鐘
  D2 := strToDateTime('2004/06/08 13:00');
  D1 := strToDateTime('2004/06/07 12:00');
  ShowMessage(IntToStr(Trunc((D2-D1)*24 Dist)));// ====> 25
end;    PS:HoursBetween於Delphi5沒有,Delphi7有,
chuanchuan
一般會員


發表:11
回覆:15
積分:5
註冊:2004-05-18

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-06-15 13:01:57 IP:163.29.xxx.xxx 未訂閱
1.感謝I630521 提醒用uses DateUtils; HoursBetween能用了 但是用起來,跟(D2-D1)*24結果是一樣,有BUG,所以放棄~~ 2.版主chance36所提是可行的 Dist := 1/(24*60) ; // 誤差為1分鐘 D2 := strToDateTime('2004/06/08 13:00'); D1 := strToDateTime('2004/06/07 12:00'); ShowMessage(IntToStr(Trunc((D2-D1)*24 Dist))); 相當等於(D2-D1)*24 0.00069 誤差一分鐘 跟本人所用土法(D2-D1 0.000001)*24 算法類似(約誤差一秒) 二者試了都可以,總算 0.000001找到了依據~謝謝~ 3.至於版主change.jian的用法,小弟功力不夠,不懂,暫不追高. 4.最後小弟決定用(D2-D1)*24 0.00001 (誤差一秒),因為在此例 本人是以使用者輸入來計算,因為誤差分或秒結果一樣,若是 用抓系統日期時間來算,恐怕會有問題,為免生枝節,決定用 (D2-D1)*24 0.00001 ,謝謝大家~~
系統時間:2024-05-19 14:14:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!