Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Проблема округления даты (Double)  [new]
Lisichkin
Member

Откуда:
Сообщений: 474
Помогите! На Delphi 7 следующий код возвращает 0

uses DateUtils;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  D1, D2: TDateTime;
begin
  D1 := StrToDateTime('25.11.20 00:00');
  D2 := StrToDateTime('24.11.20 23:00');
  i := HoursBetween(D1, D2);
  ShowMessage(IntToStr(i));
end;
17 ноя 20, 20:27    [22234152]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 26836
D1 и D2 - точно даты со временем после преобразования?
17 ноя 20, 20:29    [22234154]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
defecator
Member

Откуда:
Сообщений: 39394
wadman
D1 и D2 - точно даты со временем после преобразования?

я уже не помню точно, но не должна ли быть D1 меньше (либо равна) D2 ?
17 ноя 20, 20:34    [22234156]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
Lisichkin
Member

Откуда:
Сообщений: 474
Все хуже:
HoursBetween = Round((D2-D1)*24)
(ABS я пропустил)
Так вот (D2-D1)*24 = 0.99999
17 ноя 20, 20:39    [22234157]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12319
А если так?
  D1 := StrToDateTime('25.11.2020 00:00');
  D2 := StrToDateTime('24.11.2020 23:00');
17 ноя 20, 20:48    [22234160]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12319
Lisichkin,

Посмотрите в DateUtils код HoursBetween. В XE3 такое
function HoursBetween(const ANow, AThen: TDateTime): Int64;
begin
  Result := Abs(DateTimeToMilliseconds(ANow) - DateTimeToMilliseconds(AThen))
    div (MSecsPerSec * SecsPerMin * MinsPerHour);
end;
17 ноя 20, 20:54    [22234165]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
defecator
Member

Откуда:
Сообщений: 39394
в древнем xe7/8 всё чОтко

К сообщению приложен файл. Размер - 13Kb
17 ноя 20, 21:46    [22234202]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
ъъъъъ
Member

Откуда:
Сообщений: 1350
Может, в системе у ТС нестандартный формат времени?
17 ноя 20, 21:50    [22234204]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
DimaBr
Member

Откуда:
Сообщений: 11910
старо
тынц

Сообщение было отредактировано: 17 ноя 20, 22:04
17 ноя 20, 22:01    [22234211]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
DimaBr
Member

Откуда:
Сообщений: 11910


К сообщению приложен файл. Размер - 18Kb
17 ноя 20, 22:11    [22234217]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12319
DimaBr,

Там Trunc вместо Round стоит?
18 ноя 20, 12:53    [22234524]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
alekcvp
Member

Откуда:
Сообщений: 2494
_Vasilisk_,
Ну вообще это логично: 59 минут - это не час. Но вот погрешность они не учли...
18 ноя 20, 12:57    [22234527]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
s62
Member

Откуда: Жуковский
Сообщений: 1199
Ещё один повод перейти с Delphi 7 на что-то более новое.
18 ноя 20, 13:25    [22234554]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
Lisichkin
Member

Откуда:
Сообщений: 474
К сожалению, в рамках моего проекта перейти на другую версию не возможно.

Лечится так (взял кусок из Delphi XE):
function DateTimeToMilliseconds(const ADateTime: TDateTime): Int64;
var
  LTimeStamp: TTimeStamp;
begin
  LTimeStamp := DateTimeToTimeStamp(ADateTime);
  Result := LTimeStamp.Date;
  Result := (Result * MSecsPerDay) + LTimeStamp.Time;
end;

function HoursBetween(const ANow, AThen: TDateTime): Int64;
begin
  Result := Abs(DateTimeToMilliseconds(ANow) - DateTimeToMilliseconds(AThen))
    div (MSecsPerSec * SecsPerMin * MinsPerHour);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  D1, D2: TDateTime;
begin
  D1 := StrToDateTime('25.11.20 00:00');
  D2 := StrToDateTime('24.11.20 23:00');
  i := HoursBetween(D1, D2);
  ShowMessage(IntToStr(i));
end;


P.S.
Даты произвольны и никогда не приходят в систему из StrToDateTime - а взяты из базы.

Сообщение было отредактировано: 18 ноя 20, 17:39
18 ноя 20, 17:42    [22234792]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
rgreat
Member

Откуда:
Сообщений: 6312
Извращенец.

(D1-D2) * 24 = кол-во часов.
18 ноя 20, 17:44    [22234800]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
DimaBr
Member

Откуда:
Сообщений: 11910
rgreat
Извращенец.
(D1-D2) * 24 = кол-во часов.

Не работает

К сообщению приложен файл. Размер - 12Kb
18 ноя 20, 18:42    [22234846]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12319
DimaBr
Не работает
А как должно работать? Ну сделай так
Trunc((D1 - D2) * 24 + 1 / 36000001)
18 ноя 20, 19:02    [22234863]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
defecator
Member

Откуда:
Сообщений: 39394
_Vasilisk_
DimaBr
Не работает
А как должно работать? Ну сделай так
Trunc((D1 - D2) * 24 + 1 / 36000001)


формула отработает правильно, если D1 > D2
Если D1 < D2, то будет отрицательное значение +1 лишний час
18 ноя 20, 20:58    [22234925]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
rgreat
Member

Откуда:
Сообщений: 6312
DimaBr
rgreat
Извращенец.
(D1-D2) * 24 = кол-во часов.

Не работает
Чего у тебя не работает?
Работа функции Round не соответствует твоим ожиданиям? ;)

Что ты написал - то и получил.
Чего хотел-то?

Сообщение было отредактировано: 18 ноя 20, 21:16
18 ноя 20, 21:19    [22234935]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12319
defecator
формула отработает правильно, если D1 > D2
Abs подразумевался
defecator
Если D1 < D2, то будет отрицательное значение +1 лишний час
Заменить Trunc ()на Int()
18 ноя 20, 21:46    [22234943]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
defecator
Member

Откуда:
Сообщений: 39394
_Vasilisk_
defecator
формула отработает правильно, если D1 > D2
Abs подразумевался
defecator
Если D1 < D2, то будет отрицательное значение +1 лишний час
Заменить Trunc ()на Int()


не поможет
25.11.20 00:00 - 24.11.20 23:00 по формуле получится 23
24.11.20 00:00 - 25.11.20 23:00 по формуле получится -24

Сообщение было отредактировано: 18 ноя 20, 21:50
18 ноя 20, 21:54    [22234949]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
DimaBr
Member

Откуда:
Сообщений: 11910
rgreat

>Работа функции Round не соответствует твоим ожиданиям?
Моим соответствует.

>Что ты написал - то и получил.
Что ты предложил, то я и написал, демонстрируя, что твоё предложение не работает
18 ноя 20, 21:56    [22234951]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
rgreat
Member

Откуда:
Сообщений: 6312
DimaBr
Моим соответствует.

Зачем ты тогда такую дичь с подобными округлениями написал?
Что бы запутать топик стартера?

Что ты предложил, то я и написал, демонстрируя, что твоё предложение не работает

Т.е. ты не согласен с моим утверждением что "(D1-D2) * 24 = кол-во часов."?
Картинка с другого сайта.

А уж как правильно double в integer перевести - это как бы должно быть известно каждому.
Да и не ясно, надо ли вообще в int переводить.

Сообщение было отредактировано: 18 ноя 20, 22:00
18 ноя 20, 22:03    [22234955]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
DimaBr
Member

Откуда:
Сообщений: 11910
rgreat

>Зачем ты тогда такую дичь с подобными округлениями написал?
Предложи свой вариант округления, согласно своей же формуле

>Что бы запутать топик стартера?
Топикстартер уже нашёл верное решение, считать НЕ РАЗНИЦУ В ДАТАХ, а разницу в МИЛЛИСЕКУНДАХ

>Т.е. ты не согласен с моим утверждением что "(D1-D2) * 24 = кол-во часов."?
Как видишь, твоя идея с разницей в датах натыкается на погрешность
18 ноя 20, 22:28    [22234970]     Ответить | Цитировать Сообщить модератору
 Re: Проблема округления даты (Double)  [new]
rgreat
Member

Откуда:
Сообщений: 6312
DimaBr
Предложи свой вариант округления, согласно своей же формуле

Цель этого "округления"-то хоть какая?
18 ноя 20, 22:31    [22234971]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить