powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Проблема округления даты (Double)
37 сообщений из 37, показаны все 2 страниц
Проблема округления даты (Double)
    #40019671
Lisichkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Помогите! На Delphi 7 следующий код возвращает 0

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
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;
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019673
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
D1 и D2 - точно даты со временем после преобразования?
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019675
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
wadman
D1 и D2 - точно даты со временем после преобразования?

я уже не помню точно, но не должна ли быть D1 меньше (либо равна) D2 ?
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019676
Lisichkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все хуже:
HoursBetween = Round((D2-D1)*24)
(ABS я пропустил)
Так вот (D2-D1)*24 = 0.99999
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019678
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если так?
Код: pascal
1.
2.
  D1 := StrToDateTime('25.11.2020 00:00');
  D2 := StrToDateTime('24.11.2020 23:00');
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019681
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lisichkin,

Посмотрите в DateUtils код HoursBetween. В XE3 такое
Код: pascal
1.
2.
3.
4.
5.
function HoursBetween(const ANow, AThen: TDateTime): Int64;
begin
  Result := Abs(DateTimeToMilliseconds(ANow) - DateTimeToMilliseconds(AThen))
    div (MSecsPerSec * SecsPerMin * MinsPerHour);
end;
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019698
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
в древнем xe7/8 всё чОтко
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019699
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может, в системе у ТС нестандартный формат времени?
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019704
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019708
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019895
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr,

Там Trunc вместо Round стоит?
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019897
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,
Ну вообще это логично: 59 минут - это не час. Но вот погрешность они не учли...
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40019909
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё один повод перейти с Delphi 7 на что-то более новое.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020048
Lisichkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К сожалению, в рамках моего проекта перейти на другую версию не возможно.

Лечится так (взял кусок из Delphi XE):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
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 - а взяты из базы.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020055
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извращенец.

(D1-D2) * 24 = кол-во часов.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020079
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Извращенец.
(D1-D2) * 24 = кол-во часов.

Не работает
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020090
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
Не работает
А как должно работать? Ну сделай так
Trunc((D1 - D2) * 24 + 1 / 36000001)
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020127
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
_Vasilisk_
DimaBr
Не работает
А как должно работать? Ну сделай так
Trunc((D1 - D2) * 24 + 1 / 36000001)


формула отработает правильно, если D1 > D2
Если D1 < D2, то будет отрицательное значение +1 лишний час
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020134
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
rgreat
Извращенец.
(D1-D2) * 24 = кол-во часов.

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

Что ты написал - то и получил.
Чего хотел-то?
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020136
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator
формула отработает правильно, если D1 > D2
Abs подразумевался
defecator
Если D1 < D2, то будет отрицательное значение +1 лишний час
Заменить Trunc ()на Int()
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020140
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
_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
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020141
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat

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

>Что ты написал - то и получил.
Что ты предложил, то я и написал, демонстрируя, что твоё предложение не работает
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020144
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
Моим соответствует.

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

Что ты предложил, то я и написал, демонстрируя, что твоё предложение не работает
Т.е. ты не согласен с моим утверждением что "(D1-D2) * 24 = кол-во часов."?


А уж как правильно double в integer перевести - это как бы должно быть известно каждому.
Да и не ясно, надо ли вообще в int переводить.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020150
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat

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

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

>Т.е. ты не согласен с моим утверждением что "(D1-D2) * 24 = кол-во часов."?
Как видишь, твоя идея с разницей в датах натыкается на погрешность
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020151
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
Предложи свой вариант округления, согласно своей же формуле

Цель этого "округления"-то хоть какая?
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020157
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цель любого округления получить цельночисленное значение. Топикстартеру не нужно 0,9999999999 часов
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020164
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вместо ответа на вопрос демагогия пошла.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020167
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если надо "кол-во полных часов между двумя датами":

Res:=Trunc(Abs(d1-d2)*24+0.0000000001);

P.S. При решении через DateTimeToMilliseconds стоит уменьшить зазор в часу менее чем 1 мсек получается прикол.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function HoursBetween(const ANow, AThen: TDateTime): Int64;
begin
  Result := Abs(DateTimeToMilliseconds(ANow) - DateTimeToMilliseconds(AThen))
    div (MSecsPerSec * SecsPerMin * MinsPerHour);
end;

begin
  var D1 := StrToDateTime('25.11.20 00:00');
  var D2 := StrToDateTime('24.11.20 23:00')+1/24/3600/10000;
  writeln(Trunc(Abs(D1-D2)*24+0.0000000001));
  writeln(HoursBetween(D1,D2));
end.


0
1

Мой подход и точнее и быстрей. Как-то так.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020246
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Мой подход и точнее и быстрей. Как-то так.

С чего он точнее, если выдаёт час при интервале меньше часа?..

Тогда уж правильнее сделать функцию
Код: pascal
1.
function HoursBetween(...; AccuracyMSec: Double): Integer;

, где AccuracyMSec - точность определения интервала в миллисекундах.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020269
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
alekcvp
rgreat
Мой подход и точнее и быстрей. Как-то так.

С чего он точнее, если выдаёт час при интервале меньше часа?..

Тогда уж правильнее сделать функцию
Код: pascal
1.
function HoursBetween(...; AccuracyMSec: Double): Integer;


, где AccuracyMSec - точность определения интервала в миллисекундах.


тогда уж выдавать разницу в секундах, а не в часах.
а дальше пусть кому как надо округляют
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020293
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator
тогда уж выдавать разницу в секундах, а не в часах.
а дальше пусть кому как надо округляют

999 мсек - это одна секунда или ноль?.. А 999.99?
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020302
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
alekcvp
defecator
тогда уж выдавать разницу в секундах, а не в часах.
а дальше пусть кому как надо округляют

999 мсек - это одна секунда или ноль?.. А 999.99?


я написал - в секундах

defecator

тогда уж выдавать разницу в секундах , а не в часах.
а дальше пусть кому как надо округляют
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020313
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
rgreat
Мой подход и точнее и быстрей. Как-то так.

С чего он точнее, если выдаёт час при интервале меньше часа?.
Где?!
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020318
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
alekcvp
пропущено...
С чего он точнее, если выдаёт час при интервале меньше часа?.
Где?!

Вот здесь:
Код: pascal
1.
  var D2 := StrToDateTime('24.11.20 23:00')+1/24/3600/10000;
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020319
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator
alekcvp
пропущено...

999 мсек - это одна секунда или ноль?.. А 999.99?

я написал - в секундах
defecator

тогда уж выдавать разницу в секундах , а не в часах.
а дальше пусть кому как надо округляют

И? Разница в 999 мсек - это разница в одну секунду или в ноль секунд?
А почему именно в секундах, а не в миллисекундах?
А почему именно в одну, а не в 0.1?

Вообще весь вопрос в том - насколько точно может время определять компьютер и к этой точности привязаться при определении интервалов, с учётом погрешности округления Double.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020326
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

Где мой код выдает 1?
То что ты зацитировал это задание входных параметров.
При них мой код выдает 0.
...
Рейтинг: 0 / 0
Проблема округления даты (Double)
    #40020332
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
alekcvp,

Где мой код выдает 1?
То что ты зацитировал это задание входных параметров.
При них мой код выдает 0.

Да, перепутал, извини :)
...
Рейтинг: 0 / 0
37 сообщений из 37, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Проблема округления даты (Double)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]