![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вычитение даты-времени [D2005]
oleg1963lora © (2010-04-05 09:44:00)Здравствуйте Мастера! Есть такой код:
var MyMinDateTim, MyMaxDateTime : TDateTime;
year,month,day,hour,min,sec,msec : word;
vremya, vremya2 : string;
begin
vremya:='01.03.2010 09:18';
vremya2:='01.03.2010 09:19';
MyMinDateTime:=StrToDateTime(vremya);
MyMaxDateTime:=StrToDateTime(vremya2);
MyMaxDateTime:=MyMaxDateTime-MyMinDateTime;
DecodeDateTime(MyMaxDateTime,year,month,day,hour,min,sec,msec);
При вычитании получаю:
year=1899
month=12
Day=30
Hour=0
Min=1
sec=0
msec=0.
Подскажите пожалуйста где я ошибаюсь?
Jeer (2010-04-09 16:30:00) [1]Спасся человек :)
P.S.
Нервным, parserFile.pas лучше не смотреть.
oleg1963lora (2010-04-09 16:12:00) [2]Здравствуйте Мастера!!!
Хочу поделиться радостью с трудом сделанной работы.
Пусть я плавал за моря, хоть и долго, но не зря.
Сполнил всетаки заданье хитроумного Царя! (В данном контексте - начальника) (с) Филатов
Посмотрите что у меня получилось на
http://narod.ru/disk/19548920000/ParserFile.pas.html.
Огромное спасибо Анатолию Подгорецкому, Jeer, Sha и многим другим за помощь и дельные советы.
Отдельное спасибо И.Павел за сочувствие и моральную поддержку.
Показал сделанное начальству и оно отложило мое увольнение на неопределенное время. Ядро программы сделано, дальше буду навешивать различные полезные игрушки.
(Модуль содержит конвертер из Unicode в ASCII (обычный текстовик),
парсер входного файла и загрузчик в mdb-файл)
Сделано в Code Gear Delphi 2009.
Jeer (2010-04-06 22:37:00) [3]Неужели мужика уволили ?
Да нет, в общем-то, и не зря - но всегда сердце щемит за "ушедших на дно" :(
Jeer (2010-04-05 16:50:00) [4]
> Anatoly Podgoretsky © (05.04.10 16:45) [49]
>
> > Jeer (05.04.2010 16:34:48) [48]
>
> Interpol это не интерполяция, а международный розыск преступников
Вай.. не оттуда функцию скопи-пастил :(
Anatoly Podgoretsky (2010-04-05 16:45:00) [5]> Jeer (05.04.2010 16:34:48) [48]
Interpol это не интерполяция, а международный розыск преступников
Jeer (2010-04-05 16:34:00) [6]Продолжая тему от 24 марта для страдающего oleg1963lora - может и спасет сейчас этот код его задницу, но потом надо думать о смене работы:
-Сделано исключительно в образовательных целях.
-Оптимальность не преследовалась.
Проверено на его реальных данных
Исходный:
14.03.2010 09:34:43 14.5231561660767
14.03.2010 09:46:43 14.1527576446533
14.03.2010 09:58:43 14.1268815994263
14.03.2010 10:10:43 14.1656522750854
14.03.2010 10:22:42 13.9622182846069
14.03.2010 10:34:43 13.6965284347534
14.03.2010 10:46:42 13.9146432876587
14.03.2010 10:58:43 14.36341381073
14.03.2010 11:10:43 14.207914352417
Отфильтрованный:
14.03.2010 09:36:00 14.4835441018008
14.03.2010 09:48:00 14.1499903453797
14.03.2010 10:00:00 14.1310279077839
14.03.2010 10:12:00 14.1438658810064
14.03.2010 10:24:00 13.9334751385772
14.03.2010 10:36:00 13.7198870489853
14.03.2010 10:48:00 13.9631926646318
14.03.2010 11:00:00 14.3467840074741
type
TDTArray = array of TDateTime;
var
arDT, arDT12: TDTArray; // массивы времени исходный и кратный 12 мин
arValues, arInterpol: array of double; // массивы значений исходный и прореженный интерполированный
lst: TStringList;
fsLoc: TFormatSettings;
// Поиск и возврат индекса в массиве со значением, меньшим заданного
function FindMiddle(const arValues: TDTArray; aValue: double; var idx: integer): boolean;
var i, hi: integer;
begin
Result := False;
hi := Length(arValues) - 1;
for i := 0 to hi do
if arValues[i] >= aValue then begin
if (i > 0) then Result := True;
idx := i - 1;
Break;
end;
end;
// Юникод в Анси
function UTF16_2_ANSI(const strFile: string): AnsiString;
var
inBuf: PWideChar;
hFile, fRead: Cardinal;
fSize: DWORD;
begin
Result := '';
hFile := CreateFile(PChar(strFile), GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if hFile = INVALID_HANDLE_VALUE then Exit;
inBuf := nil;
try
fSize := GetFileSize(hFile, nil);
if fSize = 0 then Exit;
GetMem(inBuf, fSize);
if ReadFile(hFile, inBuf^, fSize, fRead, nil) and (Ord(inBuf^) = $FEFF) then
Result := (WideCharLenToString(inBuf + 1, (fRead div 2) - 1));
finally
FreeMem(inBuf);
CloseHandle(hFile);
end;
end;
// Парсинг входного файла
procedure TfmStatusForm.m_Parse;
var i, j, k, m: integer;
s, ss: string;
begin
lst := TStringList.Create;
try
lst.Text := UTF16_2_ANSI(opd.FileName);
j := 0;
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fsLoc);
with fsLoc do begin
DecimalSeparator := ',';
DateSeparator := '.';
ShortDateFormat := 'DD.MM.YYYY';
ShortTimeFormat := 'HH:MM:SS';
end;
SetLength(arDT, lst.Count);
SetLength(arValues, lst.Count);
for i := 0 to lst.Count - 1 do begin
s := Trim(lst[i]);
if (Length(s) > 19) then begin
k := Pos(#32, s);
m := Pos(#9, s);
if (k > 0) and (m > 0) and (m > k) then begin
ss := Copy(s, 1, m - 1);
arDT[j] := StrToDateTime(ss, fsLoc);
arValues[j] := StrToFloat(Copy(s, m + 1, Length(s) - m), fsLoc);
Inc(j);
end;
end;
end; // for
finally
lst.Free;
end; // try
SetLength(arDT, j - 1);
SetLength(arValues, j - 1);
lbx.Clear;
fsLoc.DecimalSeparator := '.';
for i := 0 to High(arDT) do
lbx.Items.Add(DateTimetoStr(arDT[i], fsLoc) + #9 + FloatToStr(arValues[i], fsLoc));
end;
// Прореживание массива и интерполяция ( линейная )
procedure TfmStatusForm.m_Interpol;
const
cMPD = 24 * 60.0;
c12 = 12;
var
i, j, k: integer;
xi: integer;
xd: double;
x1, y1, dx, dy: double;
begin
SetLength(arDT12, Length(arDT));
SetLength(arInterpol, Length(arDT));
k := 0;
xi := round((int(arDT[0] * cMPD / c12) + 1) * c12);
for i := 0 to High(arDT) - 2 do begin
xd := xi / cMPD;
if not FindMiddle(arDT, xd, j) then break;
x1 := arDT[j];
dx := arDT[j + 1] - x1;
y1 := arValues[j];
dy := arValues[j + 1] - y1;
arInterpol[k] := y1 + (dy / dx) * (xd - x1);
arDT12[k] := xd;
Inc(k);
Inc(xi, c12);
end; // for
SetLength(arInterpol, k);
fsLoc.DecimalSeparator := '.';
lbx.Clear;
for i := 0 to High(arInterpol) do
lbx.Items.Add(DateTimetoStr(arDT12[i], fsLoc) + #9 + FloatToStr(arInterpol[i], fsLoc));
end;
Sha (2010-04-05 16:24:00) [7]Для таких данных
15.03.2010 8:18 32,98893738
15.03.2010 8:31 32,77963257
15.03.2010 8:31 29,89930534
15.03.2010 8:31 26,62034416
15.03.2010 8:31 23,75000381
15.03.2010 8:31 20,82294464
15.03.2010 8:31 18,2397995
15.03.2010 8:32 16,26139832
15.03.2010 8:35 33,5317688
15.03.2010 8:35 30,3993988
15.03.2010 8:36 27,1519928
15.03.2010 8:36 23,95251846
15.03.2010 8:44 27,1519928
15.03.2010 8:55 23,75000381
15.03.2010 10:01 32,98893738
такой результат
15.03.2010 8:24:00 32,98893738
15.03.2010 8:36:00 23,95251846
15.03.2010 8:48:00 27,1519928
15.03.2010 9:00:00 23,75000381
15.03.2010 9:12:00 23,75000381
15.03.2010 9:24:00 23,75000381
15.03.2010 9:36:00 23,75000381
15.03.2010 9:48:00 23,75000381
15.03.2010 10:00:00 23,75000381
Обрати внимание на результат для 8:36:00, попробуй его объяснить.
Sha (2010-04-05 16:19:00) [8]> oleg1963lora (05.04.10 11:24) [27]
прочитал http://www.delphimaster.ru/cgi-bin/forum.pl?id=1269419918&n=18
Похоже, для каждого 12-минутного интервала надо просто писать в БД последнее значение температуры.
var
LineNo: integer;
function GetData(var dt: TDateTime; var Temperature: double): boolean;
var
s: string;
i: integer;
begin;
inc(LineNo);
Result:=(LineNo>=0) and (LineNo0 then i:=PosEx(#32,s,i+1);
Result:=i>0;
if Result then try;
Temperature:=StrToFloat(Copy(s, i+1, MaxInt));
dt:=StrToDateTime(Copy(s, 1, i-1));
except
Result:=false;
end
end;
end;
function PutData(dt: TDateTime; Temperature: double): boolean;
begin;
Result:=true;
Form1.Memo2.Lines.Add(DateTimeToStr(dt)+' '+FloatToStr(Temperature));
end;
const
cIntervalsPerDay= 120;
function DateTimeToIntervalNo(dt: TDateTime): int64;
begin;
Result:=Trunc(dt * cIntervalsPerDay);
if Result
Игорь Шевченко (2010-04-05 15:03:00) [9]И. Павел © (05.04.10 11:41) [35]
> Коллеги, давайте не будем флудить, раз у человека серьезные
> проблемы
а кого это должно волновать ? Тебя ? Свяжись с ним по почте, реши его проблему, всех дел-то
Desdechado (2010-04-05 13:59:00) [10]
> Просто я по ходу пьесы столкнулся с вычитанием 12 минут
> из 3. Арифметически получил отрицат. число, а должен был получить 51
TDateTime - это в сутках, какие нафиг минуты?
Вычитаешь меньшее из большего, а результат: в целой части сутки, в дробной - доли суток, которые, надеюсь, сможешь перевести в часы-минуты-секунды.
oleg1963lora (2010-04-05 13:56:00) [11]
> Вот так можно проверить (+-1 сек, так как это нецелые числа
> и возникают проблемы с округлением):
Интересная идея. На мой взгляд так можно легко забить клин на год и работать только с минутами. Спасибо, сейчас попробую
И. Павел (2010-04-05 13:43:00) [12]> [41] oleg1963lora (05.04.10 13:23)
Вот так можно проверить (+-1 сек, так как это нецелые числа и возникают проблемы с округлением):
procedure TForm1.btn1Click(Sender: TObject);
var
vremya, vremya2 : string;
D1, D2:TDateTime;
MyMinDateTime, MyMaxDateTime:TDateTime;
begin
D1:=StrToDateTime('30.12.1899 0:10:59');
D2:=StrToDateTime('30.12.1899 0:13:01');
vremya:='01.03.2010 09:18';
vremya2:='01.03.2010 09:31';
MyMinDateTime:=StrToDateTime(vremya);
MyMaxDateTime:=StrToDateTime(vremya2);
MyMaxDateTime:=MyMaxDateTime-MyMinDateTime;
if (MyMaxDateTime>=D1) and (MyMaxDateTime<=D2) then Application.MessageBox('Разница между датами от 11 до 13 минут', '', 0);
end;
oleg1963lora (2010-04-05 13:23:00) [13]
> число, в сутках, которое уже можно проанализировать на
> предмет величины
Именно об этом и идет речь. Просто я по ходу пьесы столкнулся с вычитанием 12 минут из 3. Арифметически получил отрицат. число, а должен был получить 51. Такая же ситуация с переход часов в сутки, суток в месяцы и до года. Так что без полной даты-времени у меня не выходит.
Desdechado (2010-04-05 12:39:00) [14]Одного не понимаю: почему автор считает, что результат разности двух дат - это дата?
Вот из 5 апреля вычесть 1 апреля - это что, 4 апреля будет, что ли? Дуристика какая-то. Разница - 4 дня, т.е. длина интервала времени, но никак не дата. Так зачем же результат приводить к дате?
А вот эта длина интервала - суть дробное число, в сутках, которое уже можно проанализировать на предмет величины для последующих операций "сокращения входного файла".
И. Павел (2010-04-05 11:49:00) [15]Вот тут лбсуждался аналогичный вопрос:
http://forum.sources.ru/index.php?act=ST&f=11&t=81193
Anatoly Podgoretsky (2010-04-05 11:49:00) [16]> И. Павел (05.04.2010 11:41:35) [35]
Он этого не понимает, это уже вторая ветка.
Sha (2010-04-05 11:49:00) [17]> oleg1963lora (05.04.10 11:24) [27]
> Спасите мою задницу!
Мысленно строим график результатов измерений от времени (непрерывная кусочно-линейная функция).
Сохраняем ее значения в точках, соответствующих нужным моментам времени.
И. Павел (2010-04-05 11:42:00) [18]деля -> делу :)
прошедших с како1-то даты -> прошедших с какой-то даты
И. Павел (2010-04-05 11:41:00) [19]Коллеги, давайте не будем флудить, раз у человека серьезные проблемы, а отвечать по деля.
Формат TDateTime представляет дату как дробное число, в котором целая часть - число дней, прошедших с како1-то даты 1989 года, а дробная часть - часть от прошедшего дня (например 0.5 - это полдень). Исходя из этого можно анализировать разницу между двумя датами.
> Дату привести к TDatetime и умножить на 1440 дальше остаток
> от деления на 12 и анализ результата
Вот, в частности, способ. Или просто из разницы дат выделять минуты функцией EncodeTime
Anatoly Podgoretsky (2010-04-05 11:35:00) [20]> Jeer (05.04.2010 11:26:29) [29]
Форумов не хватит.