1

I am using C++ Builder and have the following question:

I am wanting to detect if a date/time is later than another date/time, and by how much.

Here is my current code:

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;

In the above example, the following gets printed out: 31/12/1899

The difference between the two values is only 1 day. Why is: 31/12/1899 being printed, and not something like: 1?

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
Darryl Janecek
  • 399
  • 4
  • 9
  • 25
  • Just subtract them, the "-" operator returns another TDateTime that holds the difference. – Adriano Repetti Sep 12 '12 at 10:39
  • Try this.. http://stackoverflow.com/questions/833340/calculate-time-between-2-tdatetime-with-a-twist – MarsRover Sep 12 '12 at 10:42
  • The result of the subtraction is a `TDateTime`, so the output will still be in a date format. You need to extract the numerical value somehow. I'm not up on my VCL for the most recent of BCB, so I don't know the exact member function of `TDateTime` that does this. You should be able to find it quickly with the BCB help system. – Code-Apprentice Sep 12 '12 at 15:14

2 Answers2

4

The difference is 1 day, 22 hours.

TDateTime in Delphi and C++ Builder is a double, where the whole portion (the part to the left of the decimal point) stores the number of days since a base date of December 30, 1899 (see note below), and the fractional portion (the part to the right of the decimal point) is the time.

The 1899 you're seeing after the subtraction is because you have less than a full day, and therefore the whole portion of the number is zero, and as I mentioned a date of zero is the base date in December, 1899. Since your date is 1 day later than that base date (when represented as a TDateTime, the date is interpreted as December 31, 1899.

The time portion for 22 hours is approximately 0.9167 (actually, 0.916666666666667), which represents 22/24ths of a day.

Delphi's runtime library contains a unit called DateUtils, which IIRC is available to C++ Builder as well (there's a header file for it), which contains functions which may help you, like DaysBetween that you may find useful. There are C++ examples of it's use available here.

As far as equality (one date being after the other), you can use the standard >, <, >=, <=, !=, and == operators. I've demonstrated this below as well.

Here's a quick example (in Delphi, as I don't have C++ Builder installed on this machine) that might explain:

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.

This produces this output:

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

NOTE: The base date was established by Microsoft for COM, and for compatibility reasons Delphi/C++ Builder adopted it.

Synetech
  • 9,643
  • 9
  • 64
  • 96
Ken White
  • 123,280
  • 14
  • 225
  • 444
0

You can use your normal -, +, <, >,== and = with TDateTime.

So to see if one date is ahead of another, you can, for example, subtract them and see if the result is greater or lesser than zero.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
  • Be careful about time-zone jumps http://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result – huseyin tugrul buyukisik Sep 12 '12 at 10:46
  • @tu, `TDateTime` is basically a `double` that holds the date as the integer part, and the time as the fraction, so I believe it doesn't care about time zones, I'm not _quite_ sure though. – SingerOfTheFall Sep 12 '12 at 10:50
  • @Darryl, try to get both of your `testCompound`s like this: `ReplaceTime( testFirstDate, testFirstTime)` – SingerOfTheFall Sep 12 '12 at 11:53
  • @SingerOfTheFall: I have tried this: TDateTime testCombined1 = ReplaceTime(testFirstDate,testFirstTime). But I get this error: E2285 Could not find a match for 'TDateTime::TDateTime(const TDateTime&)' – Darryl Janecek Sep 12 '12 at 12:42
  • What do I do with the const part. As I think this is the piece I am misunderstanding. – Darryl Janecek Sep 12 '12 at 13:12
  • To see if one date is "ahead of another", you don't have to subtract and check the difference. `if (DateTime1 > DateTime2) { std::cout << "Date1 is after Date2";` works just fine, and there's no subtraction involved - it's a straight boolean test. – Ken White Dec 07 '12 at 03:32