|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Столкнулся сегодня с одним неприятным багом. StrToTime('18:21:00') возвращает 0,764583333333333 а вот Time для 18:21:00 возвращает уже 0,764594861111111 Значения эти явно разные, а вот приведение к TTime(0.764594861111111) или TTime(0.764583333333333) дает одинаковое время 18:21:00 И это порождает проблему при попытке определить попадает ли текущее время в заданный временной интервал, т.к. правая граница интервала оказывается меньше чем ожидается. Конечно можно тупо добавить секунду к правой границе, но хочется по нормальному решить проблему. Функция SecondsBetween() тоже не учитывает этот момент и дает на граничном значении тоже неверный результат. Итак коллеги, что с этим делать? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 18:43 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Страдалецъ, правильное значение - первое ((18+21/60)/24). А как вы получаете значение функции Time() ? Видимо вызов функции произошел не ровно в 18:21, а несколько позднее. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 18:52 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Проверку как делаете? TimeInRange() корректно работает? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 18:53 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Страдалецъ Итак коллеги, что с этим делать? Если нужна точность до долей секунды - не стоит оперировать такими типами данных ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 18:54 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 18:56 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
s62 правильное значение - первое ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 18:56 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Второе значение соответствует, с точностью до миллисекунд, 18:21:00.996 Соколинский Борис, смотря как округлять. Если вниз, то да. Ну и ТС не указал, какая точность ему требуется - секунды, минуты, десятки миллисекунд. Соколинский Борис Они оба правильные, соответствуют входным данным c точностью до секунды. Первое значение правильное в том смысле, что в пределах точности TTime оно соответствует 18:21, а второе в этих пределах точности - не соответствует. Но понятно, что вы написали об измерении времени. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 19:05 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Попробую иначе изложить проблему. Имеем интервал времени с 18:00:00-18:01:00, где каждые 20 секунд должно произойти событие. Таких событий должно быть 4: 18:00:00 18:00:20 18:00:40 18:01:00 а по факту их происходит только 3 по вышеописанной причине. Код простой: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
При T=18:01:00 TimeInRange возвращает ложь, а не истину, как ожидалось именно потому-что Time содержит лишние миллисекунды и по факту время больше 18:01:00 ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 19:24 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Соколинский Борис, не очень внимательно прочитал первое сообщение ТС сначала, прагматическую сторону в конце пропустил. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 19:36 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
В принципе проблему решает такая вот хрень: Код: pascal 1.
Но как-то это стремненько выглядит. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 19:41 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Страдалецъ, учитывайте, что таймер отчитывает время не идеально точно. Поэтому последнее срабатывание может произойти позже конца интервала - как у вас рассчитано, что интервал - ровно три раза по 20 сек. Я бы может быть добавил какую-то дельту, учитывающую возможную погрешность таймера - если задача это допускает (что последнее событие произойдет несколько позднее конца заданного интервала). Если не допускает, то наверное надо логику менять. Код: pascal 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 19:49 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Страдалецъ>а вот Time для 18:21:00 возвращает уже 0,764594861111111 И как ты это выяснил? Руками пересчитал минуты и секунды в биты, или системные часы остановил? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 20:50 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Вы используете TTimer? оО Сделайте отдельную нить, в которой вычисляете время следующего запуска и просто его ждете... Когда наступило событие по таймауту - значит время наступило и надо сгенерировать ваше событие... Конкретно под ваш пример как-то так... Но лучше рассмотреть, когда у вас массив интервалов с учетом дат, и при каждой итерации определять ближайшее время запуска и просто ждать в event.WaitFor(waitTime) столько мс, сколько надо от сейчас, до этого времени запуска. wrTimeout - подождали, значит наступило событие wrSignaled - отменили ожидание, значит завершаем работу нити и больше не генерируем события Код: 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. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56.
P.S. event := TEvent.Create(nil, True, False, ''); должно быть вне нити и передавать в нить, чтобы из другой нити вызвать event.SetEvent(); для завершения работы. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 20:57 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Естественно если время работы вашего события больше чем время запуска + интервал, то какой-то запуск будет пропущен. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 21:01 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
авторИ как ты это выяснил? Руками пересчитал минуты и секунды в биты, или системные часы остановил? Довольно просто. Преобразовал T в строку и на брейкпоинт повесил условие S = '18:01:00'; Посмотрел, что находится в T в момент остановки. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 21:33 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Страдалецъ Попробую иначе изложить проблему. Имеем интервал времени с 18:00:00-18:01:00, где каждые 20 секунд должно произойти событие. Есть такие парни: Котельников и Найквист, они придумали, что если нужно что-то с частотой Ф, то проверять необходимо с частотой 2*Ф. Возможно, это относится к Вашей ситуации. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 21:48 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Страдалецъ а вот Time для 18:21:00 возвращает уже 0,764594861111111 В этом я несколько сомневаюсь. Страдалецъ Код простой: И не очень верный, говоря деликатно. Этот код будет верно работать только в том случае, если таймерная процедура гарантированно срабатывает каждую секунду и при этом не более чем один раз в одну и ту же секунду. С практической точки зрения такое условие невыполнимо, то есть этот код всегда будет лажать, что бы Вы ни делали. Если установить у таймера Interval больше 1000 - он будет пропускать часть моментов срабатываний, если же установить Interval меньше 1000 - он будет делать двойные срабатывания. Это просто ложный алгоритм, который не будет хорошо работать никогда (и манипуляции с StrToTime только на первый взгляд его вылечат). Для того, чтобы код работал верно, нужно завести некую переменную со смыслом "ожидание времени следующего срабатывания". Изначально её устанавливать в ASheduleItems[i].Start, после срабатывания - в +20 секунд, а когда она превысит AScheduleItems[i].Stop - переводить в ASheduleItems[i + 1].Start. Что же до самого срабатывания, то его надо делать по условию Time >= значение_этой_переменной. Тогда всё будет достаточно чётко. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2021, 22:17 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
softwarer если же установить Interval меньше 1000 - он будет делать двойные срабатывания. Это тоже не спасет. Если интервал 500 - тогда при 1м срабатывании будет рано, а 2е точно так же может запоздать. Без допущения лага таймера либо позволения сработать чуть раньше времени задача решения не имеет, кмк. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.09.2021, 10:29 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
s62 смотря как округлять Входные данные с точностью до секунды. Т.е. 18:21:00 это и 18:21:00.000 и 18:21:00.999 Соответственно, любые операции с полученными данными будут давать точность не более чем +/- 1с ... |
|||
:
Нравится:
Не нравится:
|
|||
16.09.2021, 10:50 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Соколинский Борис s62 смотря как округлять Входные данные с точностью до секунды. Т.е. 18:21:00 это и 18:21:00.000 и 18:21:00.999 Соответственно, любые операции с полученными данными будут давать точность не более чем +/- 1с Если вы оперируете округленными значениями времени с точностью до секунд, округлив к ближайшему целому значению секунд, получим, что 18:21:00.999 это 18:21:01. То, что измеренное значение 18:21:00.999 попадает в интервал 18:21:00±1 сек это понятно. Так же, как оно попадает в интервал 18:21:01±1 сек. Но вообще я написал в первом сообщении не об этом, а о том, что первое значение у ТС - в пределах типа TTime соответствует 18:21:00, а второе, очевидно, соответствует вызову функции Time() в другой момент, примерно на секунду позже. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.09.2021, 12:23 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
s62 Если вы оперируете округленными значениями времени с точностью до секунд, округлив к ближайшему целому значению секунд, получим, что 18:21:00.999 это 18:21:01. В любом случае требуемая автором точность не обеспечивается. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.09.2021, 12:30 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Проблема автора в том, что у него 60 / 20 равно 4. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
16.09.2021, 12:32 |
|
Time и StrToTime возвращают разный результат для одного времени. Баг?
|
|||
---|---|---|---|
#18+
Соколинский Борис, на мой взгляд автору вообще стоило ставить интервал таймера на 20 сек, или если проверять, то не по mod, а задавая каждый раз точное время события, с которым сравнивается текущее (как softwarer написал). ... |
|||
:
Нравится:
Не нравится:
|
|||
16.09.2021, 12:34 |
|
|
start [/forum/topic.php?fid=58&fpage=12&tid=2037024]: |
0ms |
get settings: |
11ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
31ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 151ms |
0 / 0 |