2014-09-11 50 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;