2

When we use EncodeTime function EncodeTime(wHour, wMinute, wSecond, wMilliseconds) it is not assigning the millisec value to the Result.

We are using below to encode Date and Time

Result := EncodeDate(wYear, wMonth, wDay) +
  EncodeTime(wHour, wMinute, wSecond, wMilliseconds);

The String that we want to parse to a DateTime has value Apr 10 2008 7:21:31:460PM but after encoding we get the output as 10/04/2008 07:21:31.

The Result contains only HH:MM:SS value and not millisec value.

Please let us know if there is anyway to format the values and store it in a variable along with millisec. *******************function which i am trying*************

function DateTimeParser(theString :string):TDateTime;
var wYear,wMonth,wDay,wHour, wMinute, wSecond,wMilliseconds : Word  ;
Date,Month,Med :String;
Time : TDateTime;
testtime,testtime1 : TSystemTime;
var  myDateTime : TDateTime;
begin
 Month := Copy(theString,1,3) ;
 if Month ='Jan' then wMonth := 01
     else if  Month ='Feb' then  wMonth := 02
     else if  Month ='Mar' then  wMonth := 03
     else if  Month ='Apr' then  wMonth := 04
     else if  Month ='May' then  wMonth := 05
     else if  Month ='Jun' then  wMonth := 06
     else if  Month ='Jul' then  wMonth := 07
     else if  Month ='Aug' then  wMonth := 08
     else if  Month ='Sep' then  wMonth := 09
     else if  Month ='Oct' then  wMonth := 10
     else if  Month ='Nov' then  wMonth := 11
     else if  Month ='Dec' then  wMonth := 12
     else ShowMessage('Not a Valid Month');
wYear           :=  StrToInt(Copy(theString,8,4)) ;
wDay            :=  StrToInt(Copy(theString,5,2)) ;
wHour           :=  StrToInt(Copy(theString,13,2)) ;
wMinute         :=  StrToInt(Copy(theString,16,2)) ;
wSecond         :=  StrToInt(Copy(theString,19,2)) ;
wMilliseconds   :=  StrToInt(Copy(theString,22,3)) ;

ShowMessage(IntToStr(wMilliseconds));

{if Copy(theString,25,2)= 'PM' then
 wHour := wHour+12;}

Result := DateUtils.EncodeDateTime(wYear, wMonth, wDay,wHour, wMinute, wSecond, wMilliseconds);
//Result := Result+DateUtils.EncodeTime(wHour, wMinute, wSecond, wMilliseconds div 100);

 myDateTime:= EncodeDate(2009,11,28)+EncodeTime(14,23,12,001);
 ShowMessage(DatetimetoStr(myDateTime));
testtime1 := testtime;


Time :=EncodeTime(wHour, wMinute, wSecond, wMilliseconds);
            ShowMessage(DateTimeToStr(Result));

**********************************************************************


end;

Any ideas?

Aurelio De Rosa
  • 21,856
  • 8
  • 48
  • 71
SSE
  • 445
  • 2
  • 10
  • 29
  • 1
    See this answer: http://stackoverflow.com/questions/1760929/how-to-encode-a-datetime-in-delphi/1760943#1760943 – Adrian Feb 28 '11 at 14:42
  • Thanks Adrian, I did try using that option but still the millisec value is not getting stored. – SSE Feb 28 '11 at 14:51
  • The result from `DateTimeParser` do contain milliseconds. But your test string `Apr 10 2008 7:21:31:460PM` does not work. You need to have the hour padded with a 0 `Apr 10 2008 07:21:31:460PM`. – Mikael Eriksson Mar 01 '11 at 10:23
  • Late to the party here, but what you may want is AsSQLTimeStamp (http://docwiki.embarcadero.com/Libraries/en/Data.DB.TParam.AsSQLTimeStamp) – Gerry Coll Oct 05 '12 at 00:25

3 Answers3

6

I might have misunderstood the problem here but perhaps it is getting stored but you don't see it. The debugger does not show milliseconds and DateTimeToStr does not either. FormatDateTime with a format string does.

var
    Date: TDateTime;
begin
    Date := EncodeDateTime(2011, 02, 28, 20, 43, 10, 12);

    //DateTimeToStr does not show milliseconds
    ShowMessage(DateTimeToStr(Date));

    //Use FormatDateTime with Format string
    ShowMessage(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz' , Date));
end;

Database

Your dbexpress tag suggests that you are trying to store the datetime in a database. I do not know about dbexpress but ADO truncates the milliseconds out of a datetime. To save with milliseconds in SQL Server with ADO you have to build the insert statement yourself. It might be the same with dbexpress.

Here is some ADO code that will save a datetime with milliseconds in SQL Server

ADOCommand1.CommandText := 'insert into DateTbl values ('''+
    FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz' , Date)+''')';
ADOCommand1.Execute;

The precision for datetime in SQL Server 3.33 milliseconds. That is not the same as in Delphi so when I save 2011-02-28 20:43:10.012 it is saved as 2011-02-28 20:43:10.013 in SQL Server. That might be a problem for you.

One solution for you could be to store the milliseconds part of a datetime in a separate integer column. That way you will always store the same value you have encoded in Delphi and you do not have to build your own insert statements.

DBExpress

I have done some testing with DBX components and they too truncates the milliseconds.

Mikael Eriksson
  • 136,425
  • 22
  • 210
  • 281
  • Hi after formatting, found that db express is trimming the millisec part while sending to database. Am getting the below error message from database. Eg : 'The dates does not match Date Passed : 01/03/2011 10:42:05.460 Existing Date shd be : 01/03/2011 10:42:05.463' – SSE Mar 01 '11 at 11:18
  • @SSE - use AsSQLTimeStamp instead. This retains the milliseconds. – Gerry Coll Oct 05 '12 at 00:29
2

use this format HH:MM:SS.ZZZ

Cheers

APZ28
  • 997
  • 5
  • 4
2

It may not be obvious to you, but in the default date and time formats, the seconds and milliseconds are usually separated by a dot (.). The example string you showed in your question Apr 10 2008 7:21:31:460PM has a colon (:) in that position. That could well cause the milliseconds to be dropped.

Marjan Venema
  • 19,136
  • 6
  • 65
  • 79
  • Hi after formatting, found that db express is trimming the millisec part while sending to database. Am getting the below error message from database. Eg : 'The dates does not match Date Passed : 01/03/2011 10:42:05.460 Existing Date shd be : 01/03/2011 10:42:05.463' Is there any way we can solve this issue with db express – SSE Mar 01 '11 at 11:23
  • @user637761: don't know dbexpress well enough to say one way or another, but it may wel be the database that is doing the trimming. I do know that for example SQL server does drop milliseconds that are passed to it. You could try TIMESTAMP columns instead of DATETIME (not sure about exact names). Perhaps TIMESTAMP columns do have a millisecond resolution in the database you are using. – Marjan Venema Mar 01 '11 at 12:23