Проверка двух переменных TDateTime

Я использую C++ Builder и у меня есть следующий вопрос:

Я хочу определить, является ли дата/время более поздней, чем другая дата/время, и насколько.

Вот мой текущий код:

TDateTime testFirstDate("11/09/2012");
TDateTime testFirstTime("14:00");

TDateTime testSecondDate("12/09/2012");
TDateTime testSecondTime("16:00");

TDateTime testCombined1 = testFirstDate + testFirstTime;
TDateTime testCombined2 = testSecondDate + testSecondTime;

TDateTime testDateDifference = testSecondDate - testFirstDate;
std::cout << testDateDifference;

В приведенном выше примере распечатывается следующее: 31/12/1899.

Разница между двумя значениями составляет всего 1 день. Почему печатается: 31.12.1899, а не что-то вроде: 1?


person Darryl Janecek    schedule 12.09.2012    source источник
comment
Просто вычтите их, оператор - вернет другой TDateTime, который содержит разницу.   -  person Adriano Repetti    schedule 12.09.2012
comment
Попробуйте следующее. stackoverflow.com/questions/833340/   -  person MarsRover    schedule 12.09.2012
comment
Результатом вычитания является TDateTime, поэтому вывод по-прежнему будет в формате даты. Вам нужно как-то извлечь числовое значение. Я не в курсе последних версий BCB в своем VCL, поэтому я не знаю точной функции-члена TDateTime, которая это делает. Вы сможете быстро найти его с помощью справочной системы BCB.   -  person Code-Apprentice    schedule 12.09.2012


Ответы (2)


Разница 1 день 22 часа.

TDateTime в Delphi и C++ Builder является двойным, где целая часть (часть слева от десятичной точки) хранит количество дней с базовой даты 30 декабря 1899 г. (см. примечание ниже), а дробная часть ( часть справа от запятой) — это время.

1899 год, который вы видите после вычитания, связан с тем, что у вас меньше полного дня, и, следовательно, вся часть числа равна нулю, и, как я уже упоминал, нулевая дата является базовой датой в декабре 1899 года. Поскольку ваша дата на 1 день позже этой базовой даты (при представлении в виде TDateTime дата интерпретируется как 31 декабря 1899 года.

Временная часть в 22 часа составляет приблизительно 0.9167 (на самом деле 0.916666666666667), что соответствует 22/24 дням.

Библиотека времени выполнения Delphi содержит модуль с именем DateUtils, который IIRC также доступен для C++ Builder (для него есть заголовочный файл), который содержит функции, которые могут вам помочь, например DaysBetween, которые могут оказаться полезными. Примеры его использования на C++ доступны здесь.

Что касается равенства (одна дата следует за другой), вы можете использовать стандартные операторы >, <, >=, <=, != и ==. Я также продемонстрировал это ниже.

Вот краткий пример (в Delphi, так как на этой машине у меня не установлен C++ Builder), который может объяснить:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, DateUtils;

var
  StartDate, EndDate, Diff: TDateTime;
begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    // Base date, formatted in US date format
    WriteLn('BaseDate: ', FormatDateTime('mm/dd/yyyy hh:nn:ss', 0));

    StartDate := EncodeDateTime(2012, 9, 11, 14, 0, 0, 0);
    EndDate := EncodeDateTime(2012, 9, 12, 16, 0, 0, 0);
    Diff := EndDate - StartDate;

    WriteLn('Diff as String: ', DateToStr(Diff));
    WriteLn('Diff as Double: ', Diff);
    WriteLn('DaysBetween: ', DaysBetween(EndDate, StartDate));

    // Equality
    WriteLn('EndDate after StartDate`, EndDate > StartDate);
    RegEx.Free;
    ReadLn;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Это производит этот вывод:

BaseDate: 12/30/1899 00:00:00
Diff as String: 12/31/1899
Diff as Double:  1.08333333332848E+0000
DaysBetween: 1
EndDate after StartDate: TRUE

ПРИМЕЧАНИЕ. Базовая дата была установлена ​​Microsoft для COM, и по соображениям совместимости Delphi/C++ Builder принял ее.

person Ken White    schedule 12.09.2012

Вы можете использовать обычные -, +, <, >, == и = с TDateTime.

Таким образом, чтобы увидеть, опережает ли одна дата другую, вы можете, например, вычесть их и посмотреть, больше или меньше нуля результат.

person SingerOfTheFall    schedule 12.09.2012
comment
Будьте осторожны со скачками часовых поясов «почему вычитание этих двух раз в 1927 году дает странный результат»> stackoverflow.com/questions/6841333/ - person huseyin tugrul buyukisik; 12.09.2012
comment
@tu, TDateTime в основном представляет собой double, который содержит дату в виде целой части и время в виде дроби, поэтому я считаю, что часовые пояса его не волнуют, хотя я вполне не уверен . - person SingerOfTheFall; 12.09.2012
comment
@Darryl, попробуй сделать так, чтобы оба твоих testCompound выглядели так: ReplaceTime( testFirstDate, testFirstTime) - person SingerOfTheFall; 12.09.2012
comment
@SingerOfTheFall: я пробовал это: TDateTime testCombined1 = ReplaceTime(testFirstDate, testFirstTime). Но я получаю эту ошибку: E2285 Не удалось найти совпадение для «TDateTime:: TDateTime (const TDateTime &)» - person Darryl Janecek; 12.09.2012
comment
Что мне делать с константной частью. Поскольку я думаю, что это часть, которую я неправильно понимаю. - person Darryl Janecek; 12.09.2012
comment
Чтобы увидеть, опережает ли одна дата другую, вам не нужно вычитать и проверять разницу. if (DateTime1 > DateTime2) { std::cout << "Date1 is after Date2"; работает просто отлично, и вычитание не требуется — это прямой логический тест. - person Ken White; 07.12.2012