#c #time #tdatetime #c builder-2009
#c #время #tdatetime #c builder-2009
Вопрос:
Я использую C Builder 2009. У меня есть дата начала 2000/01/01
и количество секунд от этой временной метки. Я хочу создать a 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 лет. Смотрите скриншоты ниже.
Как я могу добавить это количество секунд к a TDateTime
?
Комментарии:
1. Я не вижу проблемы с вашим кодом, и меня бы удивило, если
IncSeconds
бы это было сломано.2. Я использую C Builder 2009.
3. Все ставки отменяются, если вы используете компилятор 11-летней давности .
4. Я не могу обновить компилятор.
5. @Botje на самом деле, в C Builder / Delphi 2009 и даже раньше
DateUtils
функции были не очень точными. Функции были переписаны в XE для решения проблем с точностью.
Ответ №1:
В вашем коде нет ничего плохого. И на самом деле, я не могу воспроизвести проблему, которую вы описываете, используя значения, которые вы показали. Результат, который я получаю 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);
Ответ №2:
Я нашел некоторые обходные пути. Я добавляю дни, а затем добавляю оставшиеся секунды. Я думаю, что это ошибка в 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);
Комментарии:
1. К вашему сведению,
int restOfSeconds = seconds - days*86400;
можно упроститьint restOfSeconds = seconds % 86400;
и использоватьSyutils::SecsPerDay
константу вместо жесткого кодирования86400
.