2014-09-11 54 views
1

嗨我需要在delphi中添加小時,我有幾個小時的數據用這種方式表達了9:18:02,8:15:19,9:22:13我需要知道這些小時的總數,例如這三個數據將總計爲26:55:34。這個想法是知道用戶花費的小時數。感謝幫助。如何使用Delphi來總結小時?

+2

另一個版本重新計算到秒,然後添加? – whosrdaddy 2014-09-11 06:27:05

+0

這可能是一個選項,但我如何將小時轉換爲秒? – 2014-09-11 06:30:51

+0

將小時數乘以60得到分鐘數。乘以60分鐘得到秒。 – 2014-09-11 06:35:12

回答

2

如果你想whole小時:

var 
    totalHours: Integer; 
... 
totalHours := HoursBetween(0,StrToTime(s1) + StrToTime(s2) + StrToTime(s3)); 

如果你想fractional小時:

var 
    fracHours: Double; 
... 
fracHours := HourSpan(0,StrToTime(s1) + StrToTime(s2) + StrToTime(s3)); 

其中S1,S2,S3是你的時間值表示爲字符串。

請注意,使用日期,時間值時,請查看RTL提供的內容:Date and Time Support


爲在mg30rg的評論中提到,有超載的StrToTimeTryStrToTime,處理時間字符串的特定區域轉換以及消除可能的主題改變應用程序轉換設置的效果版本。閱讀以上鍊接中關於TFormatSettings的文檔說明。

實際代碼還應該處理可能的轉換錯誤。

+0

這是一種依賴於語言環境的解決方案,並不一定適用於所有環境。如果你想在每個Locale中工作,你必須創建一個'TFormatSettings'實例並設置'LongTimeFormat'和'TimeSeparator'字段,然後調用'StrToTime(const Time:string; const FormatSettings:TFormatSettings):TDateTime' 'TFormatSettings'實例作爲第二個參數。 – mg30rg 2014-09-11 09:27:39

+0

@ mg30rg,是的,這是正確的,並使它更安全,應該使用[TryStrToTime](http://docwiki.embarcadero.com/Libraries/en/System.SysUtils.TryStrToTime)。 – 2014-09-11 09:38:09

+0

StrToTime是一個非常不安全的函數。 – 2014-09-11 09:39:34

1

這裏有一個回到基本指導你如何實現這個自己:

  1. 分割上:琴絃拿到三根弦,時,分,秒。使用StrToInt將這三個值轉換爲整數。
  2. 使用這樣一個事實,即一分鐘內有60秒鐘,一小時內有60分鐘可將持續時間轉換爲秒。
  3. 求和值。
  4. 將秒除以60,其餘爲最後秒數,除法結果爲總分鐘數。使用divmod
  5. 將上一步計算的總分鐘數除以60.其餘爲分鐘數,除法結果爲小時數。使用Format重組包含最終答案的字符串。

換句話說,您將時間跨度轉換爲秒,將它們加起來,然後再轉換回小時,分鐘和秒。這裏涉及的算術非常基礎。


但是,System.TimeSpan單位已經有你需要的。

{$APPTYPE CONSOLE} 

uses 
    System.SysUtils, 
    System.TimeSpan; 

var 
    Total: TTimeSpan; 

begin 
    Total := TTimeSpan.Parse('9:18:02') + TTimeSpan.Parse('8:15:19') + 
    TTimeSpan.Parse('9:22:13'); 
    Writeln(Format('%d:%.2d:%.2d', [Total.Days * 24 + Total.Hours, Total.Minutes, 
    Total.Seconds])); 
end. 

輸出:

 
26:55:34 

這是一個有點凌亂我在你需要的天轉換爲小時猜想,但應該不會太困難。

+1

這是一個醜陋的黑客。你應該使用德爾福的RTL函數 – 2014-09-11 09:40:06

+1

@JensBorrisholt不是很難看。簡單實施,當然值得了解如何。阿斯克爾可能從來沒有這樣做過,因此理解這個概念非常有用。與你的回答相反,RTL已經擁有了所有必需的東西,即'TTimeSpan'。也許你正在使用Delphi的舊版本。 – 2014-09-12 06:15:46

0

德爾福裏沒有任何東西可以給你想要的結果。

我給你寫一個小班做蜱爲您提供:

unit HourU; 

interface 

{$M+} 
uses 
    SysUtils; 

const 
    TimeSeparatorUsed: Char = ':'; 

Type 
    THour = record 
    private 
    FHours: Word; 
    FMinutes: Word; 
    FSeconds: Word; 
    public 
    constructor Create(aDateTime: TDateTime); 
    function ToString: String; 
    function ToLongString: String; 
    property Hours: Word read FHours; 
    property Minutes: Word read FMinutes; 
    property Seconds: Word read FSeconds; 
    end; 

    THourCalculator = class 
    private 
    FTotalHours: Double; 
    FFormatSettings: TFormatSettings; 
    function GetTotalHours: THour; 
    public 
    constructor Create; 
    function Add(const Value: Double): THourCalculator; overload; 
    function Add(const Value: String): THourCalculator; overload; 
    property TotalHours: THour read GetTotalHours; 
    end; 

implementation 

{ THourCalculator } 

constructor THourCalculator.Create; 
begin 
    inherited; 
    FTotalHours := 0; 
    FFormatSettings := TFormatSettings.Create; 
    FFormatSettings.TimeSeparator := TimeSeparatorUsed; 
end; 

function THourCalculator.GetTotalHours: THour; 
begin 
    Result := THour.Create(FTotalHours); 
end; 

function THourCalculator.Add(const Value: String): THourCalculator; 
var 
    Time: TDateTime; 
begin 
    if TryStrToTime(Value, Time, FFormatSettings) then 
    Add(Time); 
    Result := Self; 
end; 

function THourCalculator.Add(const Value: Double): THourCalculator; 
begin 
    FTotalHours := FTotalHours + Value; 
    Result := Self; 
end; 

{ THour } 

constructor THour.Create(aDateTime: TDateTime); 
var 
    Value: TDateTime; 
    MSec: Word; 
begin 
    Value := aDateTime - Trunc(aDateTime); 
    DecodeTime(Value, FHours, FMinutes, FSeconds, MSec); 
    inc(FHours, Trunc(aDateTime) * HoursPerDay); 
end; 

function THour.ToLongString: String; 
begin 
    Result := Format('%d Hours, %d Minutes and %d Seconds', [FHours, FMinutes, FSeconds]); 
end; 

function THour.ToString: String; 
begin 
    Result := Format('%d%1:s%d%1:s%d', [FHours, TimeSeparatorUsed, FMinutes, FSeconds]); 
end; 

end. 

首先保存單位,並將其添加到應用。

那麼這裏有一個如何使用它的一個例子:

uses 
    HourU; 

procedure TForm2.Button1Click(Sender: TObject); 
var 
    HourCalculator: THourCalculator; 
    Hour: THour; 
begin 
    HourCalculator := THourCalculator.Create; 
    Hour := HourCalculator.Add('9:18:02').Add('8:15:19').Add('9:22:13').TotalHours; 
    ShowMessage(Hour.ToString); 
    ShowMessage(Hour.ToLongString); 
    FreeAndNil(HourCalculator); 
end; 
+0

您應該檢查並更正拼寫錯誤 – 2014-09-11 10:08:57

+1

忽略TryStrToTime的失敗似乎不明智 – 2014-09-11 10:32:35

+0

Yuo是對的David。該代碼應該如何處理失敗TryStrToTime – 2014-09-11 10:45:17

-1

這裏使用TTimeSpan

uses 
    Timespan; 

type 
    TTimeSpanHelper = record helper for TTimeSpan 
    private 
    function TotalHours: Integer; 
    public 
    function sAdd(const Value: String): TTimeSpan; 
    function ToString: String; 
    function ToLongString: String; 
    end; 


{ TTimeSpanHelper } 

function TTimeSpanHelper.sAdd(const Value: String): TTimeSpan; 
begin 
    Result := Add(TTimeSpan.Parse(Value)); 
end; 

function TTimeSpanHelper.ToLongString: String; 
begin 
    Result := Format('%d:%d:%d', [TotalHours, Minutes, Seconds]); 
end; 

function TTimeSpanHelper.ToString: String; 
begin 
    Result := Format('%d Hours, %d Minutes and %d Seconds', [TotalHours, Minutes, Seconds]); 
end; 

function TTimeSpanHelper.TotalHours: Integer; 
begin 
    Result := Days * HoursPerDay + Hours; 
end; 


procedure TForm2.Button1Click(Sender: TObject); 
var 
    HourCalculation: TTimeSpan; 
begin 
    HourCalculation := TTimeSpan.Parse('9:18:02').sAdd('8:15:19').sAdd('9:22:13'); 
    ShowMessage(HourCalculation.ToString); 
    ShowMessage(HourCalculation.ToLongString); 
end;