日期/时间操纵 - 友善的倒数字符串 [英] Date/Time manipulation - friendly countdown string

查看:204
本文介绍了日期/时间操纵 - 友善的倒数字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个倒数到某个日期/时间的东西。我有工作 - 至少在小时,分钟和秒钟工作正常。我的问题是当我尝试实施天,它没有给出正确的结果。我知道DateUtils单位,但是那里有很多东西,我不知道如何做,特别是因为我在数学上很糟糕。



我有一个间隔为100的计时器。然后,我有一个全局 fDestDT 作为目的地日期/时间,以倒计时为基础。在定时器中,我有一个本地的TDateTime称为 DT 。然后我将它分解成多个字符串,并将它们放在一起,成为1个友好的字符串...

  procedure TForm1.TmrTimer发件人:TObject); 
var
DT:TDateTime;
D,H,N,S:String;
Str:String;
begin
DT:= fDestDT - Now; // fDest =目的日期/倒计时时间
//只需要使用's'格式复制数字
D:= FormatDateTime('d',DT)+'Days'; //获取天数
H:= FormatDateTime('h',DT)+'小时'; //获取小时数
N:= FormatDateTime('n',DT)+'Minutes'; //获取分钟数
S:= FormatDateTime('s',DT)+'Seconds'; //获取秒数
Str:= D +','+ H +','+ N +','+ S; //建立友好的字符串
如果lblTitle.Caption<> Str then
lblTitle.Caption:= Str; //仅当更改字幕时更改字幕
end;

它应该会出来像...



0天,3小时,1分钟,12秒



但是,当倒数的日期/时间是今天的日期时,它显示30天...



30天,3小时,1分钟,12秒



我推测,如果我提前提前1个月,它也不会正确显示。如何正确获取天数? DateUtils中有什么可以使我的大部分工作比我已经更好吗?



编辑:
修复!问题是我在第一个代码段中使用 DT:= fDestDT - Now; 是正确的,但在转换为使用 DateUtils之后,它是愚蠢的减去。 DaysBetween 而不是我需要删除那个减法,只需设置 DT:= Now;



工作代码:

  procedure TForm1.TmrTimer(Sender:TObject); 
var
DT:TDateTime;
天,小时,ins,秒:词;
SDays,SHours,SMins,SSecs:String;
Str:String;
begin
DT:=现在;
Days:= DaysBetween(DT,fDestDT);
时间:=小时(fDestDT,DT)mod 24; //删除总天数
Mins:= MinutesBetween(DT,fDestDT)mod 60;
Secs:= SecondsBetween(DT,fDestDT)mod 60;
如果Days = 1,则SDays:='Day'else SDays:='Days';
如果小时= 1,那么SHours = ='Hour'else SHours:='Hours';
如果Mins = 1 then SMins:='Minute'else SMins:='Minutes';
如果Secs = 1 then SSecs:='Second'else SSecs:='Seconds';
Str:=格式('%d'+ SDays +'%d'+ SHours +'%d'+ SMins +'%d'+ SSecs,
[Days,Hours,Mins,Secs]);
if lblTime.Caption<> Str then
lblTime.Caption:= Str;
结束


解决方案

请参阅 DaysBetween HoursBetween MinutesBetween SecondsBetween DateUtils 中。你必须做一些小数学。 :)



这是一个示例控制台应用程序来演示:

 程序Project2; 

{$ APPTYPE CONSOLE}

使用
SysUtils,DateUtils;

procedure ShowTimeDiff(const StartDate,OldDate:TDateTime);
var
天,小时,小时,秒,字;
OutputText:string;
begin
Writeln(Format('Start:%s,Old:%s',
[FormatDateTime('mm / dd / yyyy hh:nn:ss',StartDate),
FormatDateTime('mm / dd / yyyy hh:nn:ss',OldDate)]));
Days:= DaysBetween(StartDate,OldDate);
Hours:= HoursBetween(OldDate,StartDate)mod 24; //删除总天数
Mins:= MinutesBetween(StartDate,OldDate)mod 60;
Secs:= SecondsBetween(StartDate,OldDate)mod 60;
OutputText:=格式('%d天,%d小时,%d分钟,%d秒',
[天,小时,明斯,秒]);
WriteLn(OutputText);

end;

var
BeginDate,EndDate:TDateTime;
begin
BeginDate:= Now;
EndDate:= BeginDate - 0.5; //大约12个小时前
ShowTimeDiff(BeginDate,EndDate);

EndDate:= BeginDate - 2.53724; //创建日期约2 1/2天前
ShowTimeDiff(EndDate,BeginDate);

EndDate:= BeginDate - 5.75724; //创建日期约5 3/4天前
ShowTimeDiff(BeginDate,EndDate);
ReadLn;
结束。

生成以下输出:



< img src =https://i.stack.imgur.com/dfB8G.pngalt =时差>



请注意, DaysBetween HoursBetween之间是有意的表明函数总是返回正值,所以参数的顺序不是重要。这在文档中提到。


I'm building something which has a countdown to a certain date/time. I have it working - at least the Hours, Minutes, and Seconds work fine. My problem is when I try to implement Days, it does not give the correct result. I know about the DateUtils unit, but there's so much stuff there and I don't know how to do this, especially since I'm horrible at math.

I have a timer with interval at 100. Then I have a global fDestDT for the destination date/time to base the countdown off of. In the timer, I have a local TDateTime called DT. I then break it into multiple strings and put them back together into 1 'friendly' string...

procedure TForm1.TmrTimer(Sender: TObject);
var
  DT: TDateTime;
  D, H, N, S: String;
  Str: String;
begin
  DT:= fDestDT - Now; //fDest = destination date/time of countdown
  //Need to format only plural numbers with 's'
  D:= FormatDateTime('d', DT)+' Days';    //Get number of days
  H:= FormatDateTime('h', DT)+' Hours';   //Get number of hours
  N:= FormatDateTime('n', DT)+' Minutes'; //Get number of minutes
  S:= FormatDateTime('s', DT)+' Seconds'; //Get number of seconds
  Str:= D+', '+H+', '+N+', '+S;           //Build friendly string
  if lblTitle.Caption <> Str then
    lblTitle.Caption:= Str;               //Update caption only if it's changed
end;

It should come out something like...

0 Days, 3 Hours, 1 Minute, 12 Seconds

But instead the days are showing wrong, when the Date/Time of the countdown is on today's date, it is showing 30 Days...

30 Days, 3 Hours, 1 Minute, 12 Seconds

I presume that if I were to put it more than 1 month in advance, it would also not show correctly either. How do I get the number of days properly? And is there anything in the DateUtils unit that can automate most of this work better than I already am?

EDIT: FIXED! The problem was I was stupidly subtracting with DT:= fDestDT - Now; which was correct in my first code snippet, but after converting to use DateUtils.DaysBetween instead, I needed to remove that subtraction, and just set DT:= Now;.

Working code:

procedure TForm1.TmrTimer(Sender: TObject);
var           
  DT: TDateTime;
  Days, Hours, Mins, Secs: Word;
  SDays, SHours, SMins, SSecs: String;
  Str: String;
begin     
  DT:= Now;
  Days:= DaysBetween(DT, fDestDT);
  Hours:= HoursBetween(fDestDT, DT) mod 24; // Remove total days
  Mins:= MinutesBetween(DT, fDestDT) mod 60;
  Secs := SecondsBetween(DT, fDestDT) mod 60;
  if Days =  1  then SDays:=  'Day'    else SDays:=  'Days';
  if Hours = 1  then SHours:= 'Hour'   else SHours:= 'Hours';
  if Mins =  1  then SMins:=  'Minute' else SMins:=  'Minutes';
  if Secs =  1  then SSecs:=  'Second' else SSecs:=  'Seconds';
  Str:= Format('%d '+SDays+' %d '+SHours+' %d '+SMins+' %d '+SSecs,
    [Days, Hours, Mins, Secs]);
  if lblTime.Caption <> Str then
    lblTime.Caption:= Str;
end;

解决方案

See DaysBetween, HoursBetween, MinutesBetween, and SecondsBetween in DateUtils. You have to do some minor math. :)

Here's a sample console app to demonstrate:

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils, DateUtils;

procedure ShowTimeDiff(const StartDate, OldDate: TDateTime);
var
  Days, Hours, Mins, Secs: Word;
  OutputText: string;
begin
  Writeln(Format('Start: %s, Old: %s',
      [FormatDateTime('mm/dd/yyyy hh:nn:ss', StartDate),
      FormatDateTime('mm/dd/yyyy hh:nn:ss', OldDate)]));
  Days := DaysBetween(StartDate, OldDate);
  Hours := HoursBetween(OldDate, StartDate) mod 24; // Remove total days
  Mins := MinutesBetween(StartDate, OldDate) mod 60;
  Secs  := SecondsBetween(StartDate, OldDate) mod 60;
  OutputText := Format('  %d days, %d hours, %d min, %d secs',
                       [Days, Hours, Mins, Secs]);
  WriteLn(OutputText);

end;

var
  BeginDate, EndDate: TDateTime;
begin
  BeginDate := Now;
  EndDate := BeginDate - 0.5;   // about 12 hours earlier
  ShowTimeDiff(BeginDate, EndDate);

  EndDate := BeginDate - 2.53724;  // Create date about 2 1/2 days earlier
  ShowTimeDiff(EndDate, BeginDate);

  EndDate := BeginDate - 5.75724;  // Create date about 5 3/4 days earlier
  ShowTimeDiff(BeginDate, EndDate);
  ReadLn;
end.

Produces the following output:

Note that the reversal of parameter order between DaysBetween and HoursBetween is intentional to demonstrate that the functions always return positive values, so the order of the parameters isn't important. This is mentioned in the documentation.

这篇关于日期/时间操纵 - 友善的倒数字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆