Ошибка времени кодирования в Delphi 2010

Когда мы используем функцию EncodeTime EncodeTime(wHour, wMinute, wSecond, wMilliseconds), она не присваивает результату значение в миллисекундах.

Мы используем ниже для кодирования даты и времени

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

Строка, которую мы хотим преобразовать в DateTime, имеет значение Apr 10 2008 7:21:31:460PM, но после кодирования мы получаем вывод как 10/04/2008 07:21:31.

Результат содержит только значение HH:MM:SS, а не значение в миллисекундах.

Пожалуйста, сообщите нам, есть ли способ отформатировать значения и сохранить их в переменной вместе с миллисекундами. *******************функция, которую я пробую*************

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;

Любые идеи?


person SSE    schedule 28.02.2011    source источник
comment
См. этот ответ: stackoverflow.com/questions/1760929/   -  person Adrian    schedule 28.02.2011
comment
Спасибо, Адриан, я пытался использовать эту опцию, но значение в миллисекундах все равно не сохраняется.   -  person SSE    schedule 28.02.2011
comment
Результат DateTimeParser содержит миллисекунды. Но ваша тестовая строка Apr 10 2008 7:21:31:460PM не работает. Вам нужно, чтобы час был дополнен 0 Apr 10 2008 07:21:31:460PM.   -  person Mikael Eriksson    schedule 01.03.2011
comment
Опоздал на вечеринку, но вам может понадобиться AsSQLTimeStamp (docwiki. embarcadero.com/Libraries/ru/)   -  person Gerry Coll    schedule 05.10.2012


Ответы (3)


Возможно, я неправильно понял проблему, но, возможно, она сохраняется, но вы этого не видите. Отладчик не показывает миллисекунды, и DateTimeToStr тоже. FormatDateTime со строкой формата.

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;

База данных

Ваш тег dbexpress предполагает, что вы пытаетесь сохранить datetime в базе данных. Я не знаю о dbexpress, но ADO усекает миллисекунды из datetime. Чтобы сэкономить миллисекунды в SQL Server с помощью ADO, вы должны сами создать оператор вставки. То же самое может быть и с dbexpress.

Вот некоторый код ADO, который сохранит datetime с миллисекундами в SQL Server.

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

Точность для datetime в SQL Server 3,33 миллисекунды. Это не то же самое, что в Delphi, поэтому, когда я сохраняю 2011-02-28 20:43:10.012, он сохраняется как 2011-02-28 20:43:10.013 в SQL Server. Это может быть проблемой для вас.

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

DBExpress

Я провел некоторое тестирование с компонентами DBX, и они тоже усекают миллисекунды.

person Mikael Eriksson    schedule 28.02.2011
comment
Привет, после форматирования обнаружил, что db express обрезает миллисекундную часть при отправке в базу данных. Получаю приведенное ниже сообщение об ошибке из базы данных. Например: «Даты не соответствуют дате передачи: 03.01.2011 10:42:05.460 Существующая дата: 03.01.2011 10:42:05.463» - person SSE; 01.03.2011
comment
@SSE - вместо этого используйте AsSQLTimeStamp. Это сохраняет миллисекунды. - person Gerry Coll; 05.10.2012

используйте этот формат ЧЧ:ММ:СС.ZZZ

Ваше здоровье

person APZ28    schedule 28.02.2011

Для вас это может быть неочевидно, но в форматах даты и времени по умолчанию секунды и миллисекунды обычно разделяются точкой (.). Пример строки, которую вы показали в своем вопросе Apr 10 2008 7:21:31:460PM, имеет двоеточие (:) в этой позиции. Это вполне может привести к потере миллисекунд.

person Marjan Venema    schedule 28.02.2011
comment
Привет, после форматирования обнаружил, что db express обрезает миллисекундную часть при отправке в базу данных. Получаю приведенное ниже сообщение об ошибке из базы данных. Например: «Даты не совпадают с датой передачи: 03.01.2011 10:42:05.460 Существующая дата: 03.01.2011 10:42:05.463» Есть ли способ решить эту проблему с помощью db express? - person SSE; 01.03.2011
comment
@user637761 user637761: я не знаю dbexpress достаточно хорошо, чтобы сказать так или иначе, но вполне может быть, что база данных выполняет обрезку. Я знаю, что, например, SQL-сервер отбрасывает переданные ему миллисекунды. Вы можете попробовать столбцы TIMESTAMP вместо DATETIME (не уверены в точных именах). Возможно, столбцы TIMESTAMP имеют миллисекундное разрешение в используемой вами базе данных. - person Marjan Venema; 01.03.2011