简体   繁体   中英

Add lots of seconds to TDateTime in C++Builder 2009

I am using C++Builder 2009. I have a start date 2000/01/01 and a count of seconds from this timestamp. I want to create a TDateTime with this date. I create a start point TDateTime and add seconds.

  TDateTime dt(2000,1,1,0,0,0,0);
  AnsiString sdt = "";
  DateTimeToString(sdt, "yyyy/mm/dd hh:nn:ss", dt);
  closeDateTime = dt;
  closeDateTime = IncSecond(closeDateTime,footer->secondsFromZeroDateOfFinishDocument);
  DateTimeToString(sdt, "yyyy/mm/dd hh:nn:ss", closeDateTime);

After add more than 650M seconds, the TDateTime increases by only 23 days, but should increase by more than 20 years. See screenshots below.

How can I add this number of seconds to a TDateTime ?

图片

图片

图片

There is nothing wrong with your code. And in fact, I can't reproduce the issue you describe, using the values you have shown. The output I get is 2020.09.30 08:32:21 , as expected.


That being said, the functions in the DateUtils unit were known to have accuracy issues prior to XE, when those issues were fixed. C++Builder 2009 predates XE. So, if you can't upgrade to an up-to-date version, you can at least apply the same fix that is being used in later versions:

#include <SysUtils.hpp>

namespace fixed {
    TDateTime __fastcall IncSecond(const TDateTime AValue, const __int64 ANumberOfSeconds = 1)
    {
        TTimeStamp TS = DateTimeToTimeStamp(AValue);
        double TempTime = TimeStampToMSecs(TS);
        // if the above call to TimeStampToMSecs() proves to be inaccurate (it did
        // in my test in C++, but worked fine in Delphi), you can use this instead:
        // double TempTime = (double(TS.Date) * double(MSecsPerDay)) + double(TS.Time);
        TempTime = TempTime + (ANumberOfSeconds * MSecsPerSec);
        TS = MSecsToTimeStamp(TempTime);
        return TimeStampToDateTime(TS);
    }
}

TDateTime dt(2000,1,1,0,0,0,0);
AnsiString sdt = "";
DateTimeToString(sdt, "yyyy/mm/dd hh:nn:ss", dt);
closeDateTime = dt;
closeDateTime = fixed::IncSecond(closeDateTime,footer->secondsFromZeroDateOfFinishDocument);
DateTimeToString(sdt, "yyyy/mm/dd hh:nn:ss", closeDateTime);

I found some work around. I add days, and then add rest of seconds. I thik this is bug in RTL but I can't upgrade this codebase.

  TDateTime dt(2000,1,1,0,0,0,0);
  AnsiString sdt = "";
  DateTimeToString(sdt, "yyyy/mm/dd hh:nn:ss", dt);
  closeDateTime = dt;
  int seconds = footer->secondsFromZeroDateOfFinis775hDocument;
  int days = seconds / 86400;
  int restOfSeconds = seconds - days*86400;
  closeDateTime = IncDay(closeDateTime,days);
  closeDateTime = IncSecond(closeDateTime,restOfSeconds);
  DateTimeToString(sdt, "yyyy/mm/dd hh:nn:ss", closeDateTime);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM