views:

1201

answers:

1

Hi There,

I know how to use encodedate in Delphi to encode individual YY, MM and DD into a datetime field or use encodetime to encode individual HH, SS, MM and MS into datetime field but is there a way to specify both date and time into a datetime field?

Coz with encodedate I cannot specify the time and with encodetime I cannot specify the date...

e.g. how can I set a datetime field to 2009-11-28 14:23:12.000

Please help.

Thanks.

+18  A: 

Try using the EncodeDateTime function declarated in the DateUtils unit.

function EncodeDateTime(const AYear: Word;
 const AMonth: Word;
 const ADay: Word;
 const AHour: Word;
 const AMinute: Word;
 const ASecond: Word;
 const AMilliSecond: Word): TDateTime;

See this example

uses
DateUtils;

var
  myDateTime : TDateTime;

begin

 //Your Code
 myDateTime := EncodeDateTime(2009, 11, 28, 14, 23, 12, 000);
 //Your Code


End;

Another option

uses
SysUtils;

var
myDateTime : TDateTime;
begin
 //Your Code
 myDateTime:= EncodeDate(2009,11,28)+EncodeTime(14,23,12,000);
 //Your Code    
end;

The second option works because the TDatetime It is stored as a Double (TDateTime = type Double;), with the date as the integral part (the EncodeDate function returns the integral), and time as fractional part.

The date part of the TDateTime represents the number of days that have passed since 12/30/1899. a TDateTime can be any date through 31 Dec 9999 (decimal value 2,958,465), TDateTime values can also be negative. The decimal value -693593 corresponds to 1 Jan 0001.

see theses examples

var
myDateTime : TDateTime;

Begin
myDateTime :=0; //represents 12/30/1899
myDateTime :=1; //represents 12/31/1899
myDateTime :=-1; //represents 12/29/1899
myDateTime :=-693593; //represents 01/01/0001
myDateTime := Now(); //assign the current date and time to myDateTime 

myDateTime:=Trunc(Now()); //Extract only the date part.

myDateTime:=Frac(Now()); //Extract only the time part.

myDateTime :=Now() + 1;// Add a day to the current datetime


End;

Important Note from embarcadero site :

To find the fractional number of days between two dates, simply subtract the two values, unless one of the System.TDateTime values is negative. Similarly, to increment a date and time value by a certain fractional number of days, add the fractional number to the date and time value if the System.TDateTime value is positive.

When working with negative System.TDateTime values, computations must handle time portion separately. The fractional part reflects the fraction of a 24-hour day without regard to the sign of the System.TDateTime value. For example, 6:00 am on 12/29/1899 is –1.25, not –1 + 0.25, which would be –0.75. There are no System.TDateTime values between –1 and 0.

for addtional information you can see this link

RRUZ
I'll vote this up if you explain *why* the second option works and why it is safe to do it like this. If the OP knew that he wouldn't have needed to ask. To quote Raymond Chen: "If you don't understanding why something should be done, then you've fallen into the trap of cargo cult programming" (http://blogs.msdn.com/oldnewthing/archive/2009/11/04/9917052.aspx)
mghie
The second option doesn't work, and isn't safe :-) It *will* work on dates *after* 12/30/1899, but not on dates before that (dates that encode to a negative double)
Svein Bringsli
+1 great and detailed answer
Smasher
@RRUZ: Thanks, and +1. @sveinbringsli: `TDateTime` is a horrible type to use when doing anything non-trivial, anyway. It has not only a very limited range, but more importantly it has no concept of time zones, daylight saving time, or different calendars either. So while you are correct I don't consider this a problem in the domain `TDateTime` is suitable for.
mghie
@mghie: Agreed, but I thought I'd mention it. Especially since the answer mentions dates before 13/30/1899. Also, I can't see why the second option (EncodeDate+EncodeTime) should be used when EncodeDateTime is available. But apart from this minor issue I think the answer is very thorough and good.
Svein Bringsli
It seems to me that there is some consensus that the "Another option" is not recommended. So, it would be desirable to have the answer edited to make clear in the heading "Another option (not recommended)" and explaining why.
PA
@PA: There's nothing wrong with option 2 for current dates (as specified in the question), and indeed it's the only option for older Delphi versions that don't have the DateUtils unit. See the link in my first comment, one just needs to understand the rationale behind the advice.
mghie
@mghie: Psuh him a little bit more and you'll get a complete help for Delphi ;-) @RRUZ: Very good and detailed answer!
François