【抛砖引玉】我写了一个求时间两个字符串的时间差的函数,谁有更好的方法,请进来说一下。

djfu 2005-11-25 06:36:50
谁有更好的方法,请进来说一下。

时间字符串格式: yyyy-MM-dd hh:mm:ss, 求两个时间字符串的时间差(单位:秒
)
//---------------------------------------------------------------------------
// 求时间差
// long nDelta;
// BOOL bRet = DateTimeSpan("2005-11-20 01:20:00", "2005-11-20 02:30:30",
// nelta);
// nDelta = 4230

BOOL __fastcall TForm1::DateTimeSpan(String sStartDateTime, String sEndDateTime, long &nDeltaSeconds)
{
if( (sStartDateTime.Length() != 19) || (sEndDateTime.Length() != 19) )
return FALSE;

char szTime[20];
int nYear = -1, nMon = -1, nDay = -1, nHour = -1, nMinute = -1, nSecond = -1;
memset(szTime, 0, sizeof(szTime));
strcpy(szTime, sStartDateTime.c_str());
sscanf( szTime, "%04d-%02d-%02d %02d:%02d:%02d",
&nYear, &nMon, &nDay,
&nHour, &nMinute, &nSecond);
if((nYear == -1) || (nMon == -1) || (nDay == -1) ||
(nHour == -1) || (nMinute == -1) || (nSecond == -1) )
return FALSE;

memset(szTime, 0, sizeof(szTime));
strcpy(szTime, sEndDateTime.c_str());
sscanf( szTime, "%04d-%02d-%02d %02d:%02d:%02d",
&nYear, &nMon, &nDay,
&nHour, &nMinute, &nSecond);
if((nYear == -1) || (nMon == -1) || (nDay == -1) ||
(nHour == -1) || (nMinute == -1) || (nSecond == -1) )
return FALSE;

BOOL bNeedReturnPositiveValue = FALSE;
if(sStartDateTime > sEndDateTime)
{
String sTemp;
sTemp = sEndDateTime;
sEndDateTime = sStartDateTime;
sStartDateTime = sTemp;
bNeedReturnPositiveValue = TRUE;
}

TDateTime dtStartTime(sStartDateTime.SubString(12, 8)), dtEndTime(sEndDateTime.SubString(12, 8)), dtTimeSpan;
dtTimeSpan = dtEndTime - dtStartTime;
String sTimeStr = dtTimeSpan.TimeString();
memset(szTime, 0, sizeof(szTime));
strcpy(szTime, sTimeStr.c_str());
sscanf( szTime, "%02d:%02d:%02d", &nHour, &nMinute, &nSecond);

TDateTime dtStartDay(sStartDateTime.SubString(1, 11)), dtEndDay(sEndDateTime.SubString(1, 11)), dtDaySpan;
dtDaySpan = dtEndDay - dtStartDay;

if(sStartDateTime.SubString(12, 8) > sEndDateTime.SubString(12, 8))
nDeltaSeconds = dtDaySpan.Val * 24 * 60 * 60 - nHour * 60 * 60 - nMinute * 60 - nSecond;
else
nDeltaSeconds = dtDaySpan.Val * 24 * 60 * 60 + nHour * 60 * 60 + nMinute * 60 + nSecond;
if(bNeedReturnPositiveValue)
nDeltaSeconds = - nDeltaSeconds;
return TRUE;
}
...全文
555 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
痞子酷 2005-11-29
  • 打赏
  • 举报
回复
我以前记得这么写的:
long GetDateTimeofSecond(AnsiString beginTime,AnsiString endTime )
{
//时间格式:yyyy-mm-dd hh24:mi:ss
DateSeparator = '-';
ShortDateFormat = "yyyy-mm-dd";
TDateTime bt,et;
bt=StrToDateTime(beginTime);
et=StrToDateTime(endTime);
float fLong=float(24*3600)*(et-bt);
return (long)fLong;
}

呵呵~~~接分
庄鱼 2005-11-29
  • 打赏
  • 举报
回复
哦,那是double数据类型运算误差所造成的,我在我的机器上没有发现类似误差,实际上TDateTime的精确度是到毫秒级,Borland不会在这里犯这么大的低级错误。
我仔细看了你的程序,看来问题出在你的变量声明上:
float f = dt3.Val; //----------- 应该是double!而不该是float,
//--- float 的精度通常在小数点后5-6位,
//--- 而取值超出精度范围了
long l = f * 86400;
djfu 2005-11-27
  • 打赏
  • 举报
回复
FreeFice:
我试了一下你说的,基本上可以,但是如果时间值的尾数如果不是0或5,结果总会有1秒的误差。
举例来说:
s1 = "2005-11-20 01:20:00"; s2 = "2005-11-20 02:30:33";
按照你说的方法实现如下,结果是delta = 4232;
用我的DateTimeSpan的结果是4233。
不过你的方法比较简单。

void __fastcall TForm1::Button2Click(TObject *Sender)
{
TDateTime dt1(Edit1->Text),dt2(Edit2->Text), dt3;
dt3 = dt2 - dt1;
Edit3->Text = dt3.DateTimeString();
float f = dt3.Val;
long l = f * 86400;
char sc[200];
String s;
sprintf(sc, "%d", l);
s = sc;
//ShowMessage(s);
Edit4->Text = s;

}
庄鱼 2005-11-27
  • 打赏
  • 举报
回复
哦,忘了说了,TDateTime是以double类型存放的,整数部分表示为天数,因此,你要表达相差的秒数,就要再乘上86400。
庄鱼 2005-11-27
  • 打赏
  • 举报
回复
呵呵,你说的看起来很有道理,但是你自己动手试一下就知道不是那么回事了。。。
-------------------------
void __fastcall Form1::Button1Click(TObject *Sender)
{
TDateTime T1,T2;
T1 = Now(); //-------取标准时间格式:当前时间
Edit1->Text = T1.DateTimeString(); //--- 获得yyyy-mm-dd hh:nn:ss或
//--- yyyy/mm/dd hh:nn:ss格式串

T2 = TDateTime(Edit1->Text); //--- 转换为时间格式

Edit2->Text = T2+5; //--- 运算显示
}
当然,这里没有对输入的时间格式作任何的判断,但如果都不是一个有效的时间数据,计算它还有什么意思呢?
当T1,T2的值取到以后,想怎么运算比较还不由你自己定吗?你自己看看实现起来是不是很简单呢?
djfu 2005-11-26
  • 打赏
  • 举报
回复
FreeFice(庄鱼)
=================

呵呵,你说的看起来很有道理,但是你自己动手试一下就知道不是那么回事了。。。
刘芳百事 2005-11-26
  • 打赏
  • 举报
回复
谢了,学到一招
shadowstar 2005-11-26
  • 打赏
  • 举报
回复
才一个小时啊,那太短了~~~
庄鱼 2005-11-26
  • 打赏
  • 举报
回复
要那么麻烦吗?
在BCB里有TDateTime和time类型,先将串转换为TDateTime格式,然后想怎么加减都可以,再将结果用FormatString或DateTimeString方法获取就行了。
djfu 2005-11-26
  • 打赏
  • 举报
回复
呵呵,谢谢shadowstar。
这个问题也花了我快一个多小时的时间啦。

早知道有那么一个简单的函数,我就不自己写了。

alloutoflove 2005-11-25
  • 打赏
  • 举报
回复
楼上的,Win32有没类似的函数......"想当年"花了N个小时......
shadowstar 2005-11-25
  • 打赏
  • 举报
回复
#include <DateUtils.hpp>
shadowstar 2005-11-25
  • 打赏
  • 举报
回复
楼主大可不必花心思写这样一个函数,在写它之前应该想想它的应用,如果它确实有用,那么一定有前人作了很多工作。

SecondsBetween(StrToDateTime('2005-11-20 01:20:00'),
StrToDateTime('2005-11-20 02:30:30'));
alloutoflove 2005-11-25
  • 打赏
  • 举报
回复
可以转换为Windows的时间,然后用SystemTimeToFileTime之类的函数得到一个ULARGE_INTEGER这样一个64位的数据,然后再进行相减,减后的差值再转换回标准的时间...有点走弯路,不过很久前做过计算时间差,因为涉及到年月日的天数不统一,所以做了相当一段时间...偶够笨的=_=

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧