Есть задача хранить координаты некоторых транспортных средств (ТС), с целью получения отчетов о траектории движения и пробегах.
Пока данные хранятся примитивно просто в таблице с тремя колонками: время (GMT+0), широта, долгота. (есть еще, но это не принципиально).
Так вот, есть следующий use case: Получить маршрут ТС за заданный промежуток времени. Время берется локальное — по месту положения диспетчера.
Вроде бы все просто, но как быть со переходами на зимнее/летнее время?
Как должны отрабатываться варианты: запрос за близкое время, когда перехода не было, запрос за время, когда dst менялось, и, самое интересно, если запрос попадает на время смены dst? Всегда на клиенте приводить время в GMT+0? Тогда вопрос, существует ли алгоритм определения на произвольную дату, было ли включено DST или нет?
ЗЫ. понятно, почему авиадиспетчеры живут по гринвичу
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>Привет, All!
S>Есть задача хранить координаты некоторых транспортных средств (ТС), с целью получения отчетов о траектории движения и пробегах.
S>Пока данные хранятся примитивно просто в таблице с тремя колонками: время (GMT+0), широта, долгота. (есть еще, но это не принципиально).
S>Так вот, есть следующий use case: Получить маршрут ТС за заданный промежуток времени. Время берется локальное — по месту положения диспетчера. S>Вроде бы все просто, но как быть со переходами на зимнее/летнее время?
S>Как должны отрабатываться варианты: запрос за близкое время, когда перехода не было, запрос за время, когда dst менялось, и, самое интересно, если запрос попадает на время смены dst? Всегда на клиенте приводить время в GMT+0? Тогда вопрос, существует ли алгоритм определения на произвольную дату, было ли включено DST или нет?
S>ЗЫ. понятно, почему авиадиспетчеры живут по гринвичу
Я делал програмно. Т.е. (для Windows API) через GetTimeZoneInformation(), SystemTimeToFileTime() и SystemTimeToTzSpecificLocalTime(). И уже при создании отчёта пересчитывал поле с датой/временем. Можно ещё попробывать написать процедуру, не знаю, правда, какая СУБД. Алгоритм перевода времени известен, запихнуть его в процедуру и использывать.
Sshur wrote:
> Пока данные хранятся примитивно просто в таблице с тремя колонками: время (GMT+0), широта, долгота.
Правильнее будет говорить, что время в БД хранится не в (GMT+0), а в
секундах/миллисекундах прошедших с 00:00:00 UTC 1 января, 1970 года —
формат POSIX. Так же как хранится время в соответствующих типах Java
(Date) и Delphi (DateTime), да и вероятно многих других языков.
Мысль о текущем часовом поясе (GMT) должна возникать только в двух случаях:
1. Когда мы переводим этот тип в строку xx:xx:xx (вывод)
2. Когда мы переводим строку xx:xx:xx в этот тип (ввод)
В обоих случаях для корректного перевода нам нужно знать часовой пояс,
для которого производится преобразование. На любой платформе и для
любого клиента есть функции которые этим занимаются.
Для первого случая мы указываем количество миллисекунд и часовой пояс и
получаем правильное текстовое представление. Во втором случае указываем
строку и часовой пояс и получаем количество миллисекунд.
Как правило эти функции базируются на функциях ОС под которой все
работает. А установка часового пояса и слежение за летним временем ведет
уже ОС — у вас ведь системные часы корректно переводятся?
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Как хранить время в БД навигационных данных?
Здравствуйте, mazurkin, Вы писали:
M>Правильнее будет говорить, что время в БД хранится не в (GMT+0), а в M>секундах/миллисекундах прошедших с 00:00:00 UTC 1 января, 1970 года - M>формат POSIX. Так же как хранится время в соответствующих типах Java M>(Date) и Delphi (DateTime), да и вероятно многих других языков.
Вот выписка из Борландовского хелпа:
The TDateTime class inherits a val data member declared as a double that holds the date-time value. The integral part of a TDateTime value is the number of days that have passed since 12/30/1899. The fractional part of a TDateTime value is the time of day.
никаких колличеств секунд.
А как хранил время БД- это уже её личное дело Есть много всяких вариантов.
Re[3]: Как хранить время в БД навигационных данных?
ivan_000 wrote:
> Вот выписка из Борландовского хелпа: > The TDateTime class inherits a val data member declared as a double that holds the date-time value. The integral part of a TDateTime value is the number of days that have passed since 12/30/1899. The fractional part of a TDateTime value is the time of day. > никаких колличеств секунд. > А как хранил время БД- это уже её личное дело Есть много всяких вариантов.
Забыл уже, давно не программировал Но сути написанного мной не
меняет, пусть не секунды/миллисекунды, а дни — и с другого момента
отсчета — все равно шкала относительная.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Как хранить время в БД навигационных данных?
Здравствуйте, mazurkin, Вы писали:
M>Sshur wrote:
>> Пока данные хранятся примитивно просто в таблице с тремя колонками: время (GMT+0), широта, долгота.
M>Правильнее будет говорить, что время в БД хранится не в (GMT+0), а в M>секундах/миллисекундах прошедших с 00:00:00 UTC 1 января, 1970 года - M>формат POSIX. Так же как хранится время в соответствующих типах Java M>(Date) и Delphi (DateTime), да и вероятно многих других языков.
Ну да, в моем случае MSSQL хранит время в 1/300 долях секунды с какого-то мохнатого 1753-го года. Но я не об этом, UTC это и есть GMT+0 (примерно). То есть главный вопрос — хранить ли время по нулевому меридиану, или сразу преобразовывать в локальное для диспетчера или в локальное для устройства.
Но тут мне ваш ответ понятен — храним в UTC.
Тогда вопрос следующий, как вы думаете, что должно быть в отчете о движении ТС за период с 2-х до 3-х часов за ту ночь, когда стрелки назад переводят? Или вперед?
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[3]: Как хранить время в БД навигационных данных?
Sshur wrote:
> Ну да, в моем случае MSSQL хранит время в 1/300 долях секунды с какого-то мохнатого 1753-го года. Но я не об этом, UTC это и есть GMT+0 (примерно). То есть главный вопрос — хранить ли время по нулевому меридиану, или сразу преобразовывать в локальное для диспетчера или в локальное для устройства. > Но тут мне ваш ответ понятен — храним в UTC.
Я — за UTC, хотя как сами понимаете можно без проблем хранить и в
каком-то часовом поясе, но это лишнее преобразование и путаница.
> Тогда вопрос следующий, как вы думаете, что должно быть в отчете о движении ТС за период с 2-х до 3-х часов за ту ночь, когда стрелки назад переводят? Или вперед?
Я считаю должно выводиться, то что происходит на самом деле, т.е. :
01:44
02:35
02:57
02:12
02:47
02:59
03:14
Хотя я бы продублировал это еще одной колонкой — со временем в UTC
Время в "человеческом" представлении не-непрерывно и даже нелинейно
(дополнительные секунды)! А вот в миллисекундах/секундах/днях с
определенной точки отсчета — вполне себе линейно и непрерывно.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Как хранить время в БД навигационных данных?
M>Я считаю должно выводиться, то что происходит на самом деле, т.е. :
M>01:44 M>02:35 M>02:57 M>02:12 M>02:47 M>02:59 M>03:14
M>Хотя я бы продублировал это еще одной колонкой — со временем в UTC
Нет, там на самом деле получится так: (случай с переводом назад)
02:00:00
02:00:01
...
02:59:59
02:00:00 — здесь на час назад перевели
02:00:01
..
02:59:59
03:00:00
И вообще интересно, как сработает перевод local time в utc для точек 02:00 и 3:00 в ночь перевода стрелок. По идее, при переводе стрелок вперед после двух ночи сразу наступает три, то есть в local time мы имеем разрыв, а при переводе назад — перевод из local time в utc неоднозначен.
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[5]: Как хранить время в БД навигационных данных?
Sshur wrote:
> M>02:57 > M>02:12
> Нет, там на самом деле получится так: (случай с переводом назад)
Я так и имел в виду, только написал может быть не совсем понятно.
>
> 02:59:59
> 02:00:00 — здесь на час назад перевели
> И вообще интересно, как сработает перевод local time в utc для точек 02:00 и 3:00 в ночь перевода стрелок. > По идее, при переводе стрелок вперед после двух ночи сразу наступает три, то есть в local time мы имеем разрыв, а при переводе назад — перевод из local time в utc неоднозначен.
Опять же помним: если имеется в виду перевод самой величины, то ничего
переводить не надо — момент времени выраженный в миллисекундах,
секундах, днях одинаков для любого часового пояса и на него не влияет
даже перевод стрелок. Если же нам нужно ввести строковое "человеческое"
значение (например оператором) — то тут да — неоднозначность. Надо
посмотреть как и чего делают в этом случае стандартные функции.
С точки зрения эргономики, как при выводе так и при вводе можно
отслеживать этот "час" и как-то предупреждать оператора.
Posted via RSDN NNTP Server 2.1 beta
Re[6]: Как хранить время в БД навигационных данных?
Вообще интересно, как все эти моменты учитываются в уже используемых
отечественных системах — транспортных например? Я чего-то не верю, что
все ведется в UTC.
Posted via RSDN NNTP Server 2.1 beta
Re[7]: Как хранить время в БД навигационных данных?
M>Вообще интересно, как все эти моменты учитываются в уже используемых M>отечественных системах — транспортных например? Я чего-то не верю, что M>все ведется в UTC.
Насколько я знаю, самолетные диспетчера по всему миру в UTC живут. Интересно, как с переводом железнодорожники справляются.
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[8]: Как хранить время в БД навигационных данных?
Здравствуйте, Sshur, Вы писали: S>Насколько я знаю, самолетные диспетчера по всему миру в UTC живут. Интересно, как с переводом железнодорожники справляются.
Вы не поверите: оперативно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Как хранить время в БД навигационных данных?
Здравствуйте, Sinclair, Вы писали:
S>Вы не поверите: оперативно.
Более интересно, что они делают при переводе стрелок назад, тупо стоят и ждут этот "лишний" час?
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[10]: Как хранить время в БД навигационных данных?
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, Sinclair, Вы писали:
S>>Вы не поверите: оперативно. Z>Более интересно, что они делают при переводе стрелок назад, тупо стоят и ждут этот "лишний" час?
Тупо едут медленнее
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: Как хранить время в БД навигационных данных?
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, Sinclair, Вы писали:
S>>Вы не поверите: оперативно. Z>Более интересно, что они делают при переводе стрелок назад, тупо стоят и ждут этот "лишний" час?
Я думаю, просто корректируют соответствующим образом расписание, оно же по местному времени составляется. Но все равно интересно, как отрабатывается ситуация, если поезд отправляется в 2:30 в ночь перевода стрелок назад. Это время ведь два раз наступает
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>Пока данные хранятся примитивно просто в таблице с тремя колонками: время (GMT+0), широта, долгота. (есть еще, но это не принципиально).
Вместо GMT+0 должно UTC (мировое время вроде называется, если меня не глючит ). Оно не зависит от летнего/зимнего. На стороне клиента местное время приводится к мировому. А в слое бизнес логики и базе данных все вне зависимости от часового пояса и зимнего/летнего времени.
Умный человек знает не многое, но нужное
Re[3]: Как хранить время в БД навигационных данных?
Здравствуйте, Sshur, Вы писали:
S>Тогда вопрос следующий, как вы думаете, что должно быть в отчете о движении ТС за период с 2-х до 3-х часов за ту ночь, когда стрелки назад переводят? Или вперед?
Я бы сделал так: если в отчет попадает всремя перевода стрелок, то время "контрольной точки" писать с указанием часового пояса. Колонку с UTC считаю лишней (как я уже писал в соседнем посте, на клиенте отображение в его часовом поясе, на сервере все храниться раасчитывается в UTC).
Умный человек знает не многое, но нужное
Re[2]: Как хранить время в БД навигационных данных?
Так же как хранится время в соответствующих типах Java M>(Date) и Delphi (DateTime)
Неа, Delphi по умолчанию работает с локальным временем. Например функция Now() возвращает DateTime но по локальному часовому поясу. Так что приходится переводить в UTC функцией LocalTimeToDateTime, а потом уже писать в базу.