Добавьте много секунд в TDateTime в C++Builder 2009

Я использую C++Builder 2009. У меня есть дата начала 2000/01/01 и количество секунд от этой метки времени. Я хочу создать TDateTime с этой датой. Я создаю начальную точку TDateTime и добавляю секунды.

  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);

После добавления более 650 миллионов секунд TDateTime увеличивается всего на 23 дня, но должно увеличиться более чем на 20 лет. Смотрите скриншоты ниже.

Как я могу добавить это количество секунд к TDateTime?

изображение

изображение

изображение


person lgabryel    schedule 30.09.2020    source источник
comment
Я не вижу проблем с вашим кодом, и меня бы удивило, если бы IncSeconds был этот неверный.   -  person Botje    schedule 30.09.2020
comment
Я использую C++ Builder 2009.   -  person lgabryel    schedule 30.09.2020
comment
Все ставки сняты, если вы используете компилятор 11-летней давности.   -  person Botje    schedule 30.09.2020
comment
Я не могу обновить компилятор.   -  person lgabryel    schedule 30.09.2020
comment
Срок службы C++ Builder 2009 закончился в 2011 году. Вам необходимо выполнить обновление.   -  person Botje    schedule 30.09.2020
comment
@Botje на самом деле, в C++Builder/Delphi 2009 и даже раньше функции DateUtils были не очень точными. Функции были переписаны в XE для решения проблем с точностью.   -  person Remy Lebeau    schedule 02.10.2020
comment
@RemyLebeau ... и именно поэтому вы не используете компиляторы 11-летней давности. Спасибо, что подтвердили мои подозрения :)   -  person Botje    schedule 02.10.2020


Ответы (2)


В вашем коде нет ничего плохого. И на самом деле, я не могу воспроизвести описанную вами проблему, используя показанные вами значения. Вывод, который я получаю, 2020.09.30 08:32:21, как и ожидалось.


При этом было известно, что функции в модуле DateUtils имели проблемы с точностью до XE, когда эти проблемы были исправлены. C++Builder 2009 предшествует XE. Итак, если вы не можете обновиться до актуальной версии, вы можете по крайней мере применить то же исправление, которое используется в более поздних версиях:

#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);
person Remy Lebeau    schedule 02.10.2020

Я нашел некоторую работу вокруг. Я добавляю дни, а затем добавляю остальные секунды. Я думаю, что это ошибка в RTL, но я не могу обновить эту кодовую базу.

  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);
person lgabryel    schedule 30.09.2020
comment
К вашему сведению, int restOfSeconds = seconds - days*86400; можно упростить до int restOfSeconds = seconds % 86400;, и вы можете использовать константу Syutils::SecsPerDay вместо жестко заданного 86400. - person Remy Lebeau; 02.10.2020