Как получить время города N?

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Как получить время города N?

Сообщение AlphaBlend » 05.07.2016 06:51:24

SSerge писал(а):Именно эта штука работает некорректно, если переводить требуется время, не имеющее отношения к текущему

Ах , да )))) У сервера есть Крон и еще одна табличка , где он проверяет - что сегодня на календаре ( Зима , Лето ) . Проверка запускается в 00.00 , естественно , запрос выбирается - либо зимнее время , либо летнее . У некоторых мест нету переходов и значения в табличке равны ) .
Кстати о времени на машинах ) Достаточно Один единственный раз "правильно" настроить время и дату на сервере и синхронизировать ее с NTP - в принципе больше синхронизация не понадобится , одако пренебрегать ею не стоит , запуская раз в месяц - пол-года ) Если "очень не хочется" Крон - можно написать "демона" , который так же в 00.00 будет проверять "зима/лето" и перегенерировать запрос .
О том , как руководства страны принимают решения "быть зиме или не быть " - тут уже администратор должен слушать новости и исправлять ))) От этого"форс-мажора" уже никакая автоматизация не спасет ))) Можно без "крона" и "демона" сделать запрос , который будет делать все сразу и сам - : проверять ( зима . лето ) , выбирать соответственно timezone_spring или timezone_winter. в обеденный перерыв попробую составить такой запрос )
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Re: Как получить время города N?

Сообщение resident » 05.07.2016 11:37:14

AlphaBlend писал(а):О том , как руководства страны принимают решения "быть зиме или не быть " - тут уже администратор должен слушать новости и исправлять ))) От этого"форс-мажора" уже никакая автоматизация не спасет )))

На Винде приходит автоматически обновление, вобще ни о чем думать не нужно.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Как получить время города N?

Сообщение AlphaBlend » 05.07.2016 11:50:19

resident писал(а):На Винде приходит автоматически обновление, вобще ни о чем думать не нужно


На винде все автоматически проходит - настройка времени , даты , сети , разрешения экрана , принтеров , флешек , модемов , вирусов .... :mrgreen:
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Re: Как получить время города N?

Сообщение Лекс Айрин » 05.07.2016 12:58:48

вот только на убунте у меня обновление времени приходило быстрее. Плюс, на винде зачастую приходится обновление отключать. Даже на стопроцентной лицензии.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Как получить время города N?

Сообщение SSerge » 05.07.2016 14:16:57

AlphaBlend писал(а):Если "очень не хочется" Крон - можно написать "демона" , который так же в 00.00 будет проверять "зима/лето" и перегенерировать запрос


"Зачем делать сложным то, что проще простого" (С)
Ничего там не надо проверять демоном и т.п.
Надо просто правильно пользоваться тем, что есть:

- Поставить для mysql зону сеанса для места, из времени которого переводится дата;
- Конвертировать переводимую дату в unix timestamp или utc - что больше нравится;
- Поставить для mysql зону сеанса для места, во время которого переводится дата;
- Конвертировать unix timestamp или utc во время текущей зоны;

...а то - синхронизированы часы компьютера или нет, и что они вообще показывают - для задач перевода зон не имеет никакого значения.
Более того, если я поставлю себе зону "Ханой", то время у меня на текущий момент будет правильным, а вся история переходов - неправильной.

Добавлено спустя 3 минуты 20 секунд:
resident писал(а):На Винде приходит автоматически обновление


1) На месяц позже.
2) А если вам еще и зону поменяли, никакое обновление не поможет. (Впрочем и на линуксах это придется менять вручную)
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Как получить время города N?

Сообщение AlphaBlend » 05.07.2016 23:24:49

вообще это сложный вопрос на самом-то деле ) Предложение "обратиться " к базе данных городов привело меня к такому выводу :
База будет огромная ))) вот таблица более или менее известных государств) получилось..... 204 записи!!! :shock: Было потрачено времени на это где-то 6-7 часов!! ) Теперь только представить себе , что надо узнать для каждого государства и столицы разницу времени от времени по Гринвичу, переходит ли государство или отдельная столица на зимнее и летнее время и когда они переходят ( в разных странах по-разному , как говорит Великий Гугл ) . Получается , что только создать такую базу и поддерживать ее актуальность надо уже задуматься о каком-то мало-мальски командном проекте )) И одних только государств не хватит , надо затрагивать ВСЕ известные города ) Боюсь , что количество записей в такой базе превысит 10000 :roll:


А так , конечно , вопрос интересный для Лазаруса ))) какая-нибудь функция

Код: Выделить всё
type
    TResultGetDateTimeFromSubj = (rJson , rText, rDateTime);
...

GetDateTimeFromSubject(ServerAddress:String;  ServerPort:Cardinal;  Country, City:String; TypeResult:TResultGetDateTimeFromSubj):Variant;


делала бы всю рутинную работу ))
Вложения
STC.sql.zip
(6.9 КБ) Скачиваний: 451
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Re: Как получить время города N?

Сообщение скалогрыз » 06.07.2016 00:56:37

AlphaBlend писал(а): Получается , что только создать такую базу и поддерживать ее актуальность надо уже задуматься о каком-то мало-мальски командном проекте ))

Так уже сколотили команду! :mrgreen:
с геолокацией и актуальным состояниям.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Как получить время города N?

Сообщение AlphaBlend » 07.07.2016 13:52:28

скалогрыз вот я утка тупая :evil:
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Re: Как получить время города N?

Сообщение Sharfik » 12.08.2016 03:31:55

Пишу для тех, кто будет так же как я тупить. Если взять узко получение сведений о часовых поясах из ОС Windows, то примеры вроде бы и есть в сети, но все они связаны с работой GetTimeZoneInformation. Lazarus знает эту функцию и тип данных ею передаваемый.
Список описанных в реестре временных зон читаем так
Код: Выделить всё
  {$IFDEF WINDOWS}
      cbTimeList.Clear;
      reg             := TRegistry.Create;
      reg.RootKey     := HKEY_LOCAL_MACHINE;
      reg.LazyWrite   := false;
      r               := reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones');
      //В сети много где пишут другой путь, наверно в разных версиях Win по разному все.
      if r and reg.HasSubKeys then
      begin
        ts := TStringList.Create;
        reg.GetKeyNames(ts);
        reg.CloseKey;
        for i := 0 to ts.Count -1 do
        begin
          reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\' + ts.Strings[i]);         
          sTmp:=reg.ReadString('Display');
          sTmp:=WinCPToUTF8(sTmp);
          cbTimeList.Items.Add(sTmp);
          reg.CloseKey;
        end;
        ts.Free;
      end
      else
        reg.CloseKey;
      reg.free;
  {$ELSE}
       cbTimeList.Clear;
  {$ENDIF}

Список есть, дальше что? Нужно как то получить смещение и сведения о зиме/лете во времени.
Когда я забивал поиск по теме TimeZoneInformation то мне все время выдавалась страница MSDN с описанием того, что и так уже есть в Lazarus и примеры работы с функцией получения своей временной зоны через GetTimeZoneInformation. Описываемой записью вида:
Код: Выделить всё
TIME_ZONE_INFORMATION = record
          Bias : LONG;
          StandardName : array[0..31] of WCHAR;
          StandardDate : SYSTEMTIME;
          StandardBias : LONG;
          DaylightName : array[0..31] of WCHAR;
          DaylightDate : SYSTEMTIME;
          DaylightBias : LONG;
       end;

Логично предположить, что в реестре бинарное поле TZI(из ветки списка зон) хранящее сведения о переводах времени имеет такой же формат. Но нет. Если коротко - я заколебался пытаться понять почему у меня нет перевода на лето/зиму в тех тестах где должно быть. Данные о датах просто не прописывались в переменную. Пока я случайно не наткнулся на иное описание касающееся именно реестра. Ну не умею я работать с MSDN мелкософта, там все косноязычно описано. Собственно моя проблема в том была, что поле TZI реестра имеет другую структура данных, не соответствующую WinApi функции. Оно в реестре короче по размеру.
Код: Выделить всё
_REG_TZI_FORMAT = record
        Bias         : LONG;
        StandardBias : LONG;
        DaylightBias : LONG;
        StandardDate : SYSTEMTIME;
        DaylightDate : SYSTEMTIME;
     end;

Когда тип данных исправлен, все отлично работает и читается как в примере ниже.
Код: Выделить всё
procedure ....;
var
   CityTimeDataList:TCollection....;
   Item:T....Item;
   reg   :TRegistry;
   tmpBiaseHour,
   k   :integer;
   sTimeZoneName:String;
   tziTmp:_REG_TZI_FORMAT;
   tmpDateTimeDay,
   tmpDateTimeStd:TDateTime;
begin
//....
//....
{$IFDEF WINDOWS}
      reg             := TRegistry.Create;
      reg.RootKey     := HKEY_LOCAL_MACHINE;
      reg.LazyWrite   := false;

        for k := 0 to CityTimeDataList.Count -1 do
        begin
            Item          :=CityTimeDataList.Items[k];
            sTimeZoneName :=Item.AdditionalProperty.GetString('TimeZoneName', 'NULL');
            if reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\' + sTimeZoneName) then
            begin

              reg.ReadBinaryData('TZI', tziTmp, SizeOf(tziTmp));

              if (tziTmp.Bias<>0) then
                tmpBiaseHour:=integer(tziTmp.Bias div -60)
              else
                tmpBiaseHour:=0;

              if tziTmp.DaylightDate.wMonth<>0 then //сравнивать надо именно с месяцем
              begin

                  tziTmp.DaylightDate.wYear:=DateUtils.YearOf(Now);
                  tziTmp.StandardDate.wYear:=DateUtils.YearOf(Now);

                  tmpDateTimeDay  :=DateUtils.EncodeDateTime(tziTmp.DaylightDate.wYear,tziTmp.DaylightDate.wMonth,tziTmp.DaylightDate.wDay,tziTmp.DaylightDate.wHour,tziTmp.DaylightDate.wMinute,0,0);
                  tmpDateTimeStd  :=DateUtils.EncodeDateTime(tziTmp.StandardDate.wYear,tziTmp.StandardDate.wMonth,tziTmp.StandardDate.wDay,tziTmp.StandardDate.wHour,tziTmp.StandardDate.wMinute,0,0);

                  if (DateUtils.CompareDate(now,tmpDateTimeDay)>=0)and(DateUtils.CompareDate(now,tmpDateTimeStd)<0) then
                  begin
                     //лето
                      if (tziTmp.DaylightBias<>0) then
                        tmpBiaseHour:=tmpBiaseHour+integer(tziTmp.DaylightBias div -60);
                  end
                  else begin
                    //зима
                      if (tziTmp.StandardBias<>0) then
                        tmpBiaseHour:=tmpBiaseHour+integer(tziTmp.StandardBias div -60);
                  end;

              end;

              Item.AdditionalProperty.SetValue('CurrentBiaseHour', tmpBiaseHour); //смещение в текущий момент для выбранного часового пояса

            reg.CloseKey;
          end
          else begin
             ThisApplication.SystemLog(RL_ERRORTEXT,format('Не найдена информация о применяемом в профиле часовом поясе "%s"',[sTimeZoneName]));
          end;

        end;//k

      reg.free;
  {$ELSE}

  {$ENDIF}
end;
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 759
Зарегистрирован: 20.07.2013 01:04:30

Re: Как получить время города N?

Сообщение SSerge » 12.08.2016 05:00:54

Sharfik писал(а):все отлично работает


Я как-то уже обширно намекал, позволю сказать еще раз прямо: временные зоны из реестра MS Windows - информация, имеющая нулевую степень доверия и в общем случае не распространяющаяся за пределы текущего года. Более того, пользователь вашей программы с очень большой степенью вероятности поставит себе временной пояс, не имеющий отношения к его действительному местоположению - по разным причинам, одна из которых - мнение самой MS, что это нормально и допустимо. Так что, сделать то сделали, но степень недостоверности будет всегда чрезвычайно велика.
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Как получить время города N?

Сообщение sign » 12.08.2016 06:54:55

Самая точная информация о текущем времени в данном месте, это у хороших астрологических программ. Время и зоны по всей планете, по всем закоулкам.
И сейчас вопрос не об астрологии и её месте в мире, а о времени.

Есть отличная программа, написанная на древнем Делфи - http://astrozet.net. Пишет её Зайцев.
Содержит базу, которую регулярно (по мере изменений) обновляется. Последнее обновление "upd160803.rar Обновление таблиц изменений исчисления времени от 4 августа 2016."
Скачиваем и устанавливаем бесплатный вариант программы.
И разбираемся с зонами в директории - \Zones.
А если что непонятно, стучимся к Зайцеву и просим дать структуры файлов.

Я сам с этим вопросом не разбирался (структурой файлов), мне время не нужно, но у меня самая дорогая версия программы (ZET 9 Geo), лично мною куплена для собственных нужд.
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: Как получить время города N?

Сообщение Sharfik » 12.08.2016 13:40:56

SSerge писал(а):Я как-то уже обширно намекал, позволю сказать еще раз прямо: временные зоны из реестра MS Windows - информация, имеющая нулевую степень доверия и в общем случае не распространяющаяся за пределы текущего года. Более того, пользователь вашей программы с очень большой степенью вероятности поставит себе временной пояс, не имеющий отношения к его действительному местоположению - по разным причинам, одна из которых - мнение самой MS, что это нормально и допустимо. Так что, сделать то сделали, но степень недостоверности будет всегда чрезвычайно велика.

Я это читал все, спасибо конечно было интересно. Но к вопросу это условно относится. Разговора о местоположении пользователя нет, программе вообще пофиг где пользователь. Ей надо как написано в теме "Как получить время города N?" выдавать время с учетом определенного смещения. У Windows реестр содержит готовые данные с датами, когда надо переводить часы, и как я понимаю она сама каждый год его пересчитывает, потому что дата перевода это ночь с субботы на воскресенье. Не одна БД не будет содержать все даты переводов. А если где то меняется часовой пояс и в реестре этому нет соответствия - бывает, это жизнь. Можно обновление дождаться, можно руками выбрать другой пояс, можно поправить самому реестр. Мне не нужно чтобы программа и ОС шпионила за мной и сама меняла часовые пояса, я в состоянии сам нажать две кнопки чтобы сменить время в ОС. В 90% программ наверно нет необходимости в точном соответствии времени, погрешность на то что пользователь сам поправит неверно отображаемое время допустима.
Пост выше о том, как работать именно с реестром Windows, потому что примеров такого плана нет. Мне вообще не понятно, зачем надо у систему спрашивать "Где я и какой у меня часовой пояс?", а половина примеров именно такие. А как средствами Windows высчитать по известному часовому поясу время на Аляске - ноль примеров. Собственно как и других любых.

Надо иногда думать в будущее. Программы не имеющие техподдержки по своей лицензии вообще не должны работать со своей собственной БД зон времени, ибо брошенная разработчиком на произвол судьбы программа будет выдавать косяков по времени больше чем работающая с данными ОС. Сведения как отредактировать зоны в ОС найти пользователь сможет, а сведения как редактировать временные зоны в программе про которую никто не слышал почти - нет. Кроме того, программа не работающая с данными из сети должна уметь работать оффлайн на 100% и синхронизация с серверами из сети ей не нужна(это только доп опция может быть, а не основной источник данных).

Если разработчик хочет, чтобы его программа работал в 100% соответствии с реалиями, то для Windows идеальный варианты использовать реестр системы по выше описанным причинам. Но сделать модуль, который будет проверять сведения реестра и корректировать их по более свежим данным из других источников. Тогда пользователь не будет иметь проблем с программой и будет иметь возможность синхронизировать часовые пояса с более достоверными источниками. Ему в один прекрасный момент не вылезет "не могу запуститься, потому что удаленная БД оффлайн".
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 759
Зарегистрирован: 20.07.2013 01:04:30

Пред.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7

Рейтинг@Mail.ru