Pull to refresh

JavaScript: получаем информацию о временной зоне.

Reading time 2 min
Views 581
Иногда бывает очень красиво хранить время на сервере в UTC и преобразовывать его в локальное время пользователя при выдаче страницы. По крайней мере такая задача встала в проекте, в котором я участвую. Перевод из utc в локальное время задача непростая, но по нему достаточно много информации и опубликованных алгоритмов. Все что для них нужно это данные о временной зоне клиента, но как оказалось информации об этом как раз не так уж и много.

Все опубликованное ниже результаты собственных наработок


var now = new Date();

function СheckDLT(sm, em) 
  {
   return ((new Date(em)).getTimezoneOffset() - (new Date(sm)).getTimezoneOffset());
  }

function getTZLowerBound( start, end, cmp )
  {
   var nstart, count, count2;
   count = end - start;

   while(count>0)
     {
      end = start + count;
      nstart = start + ( count2 = Math.floor(count / 2) );
      if ( cmp(СheckDLT(nstart,end)) )
        {
         start = nstart + 1;
         count -= count2 + 1;
        }
      else
        count = count2;
     }
   return [start, -(new Date(start)).getTimezoneOffset()];
  }

var dlt = Date.UTC(now.getFullYear(), 0, 1, 0, 0, 0, 0),
std = Date.UTC(now.getFullYear(), 6, 1, 0, 0, 0, 0);

if(СheckDLT(dlt,std))
  {
   dlt = getTZLowerBound(dlt,std, function (b) {return (b<0)});
   std = getTZLowerBound(Date.UTC(now.getFullYear(), 6, 1, 0, 0, 0, 0),
                        Date.UTC(now.getFullYear(), 11, 1, 0, 0, 0, 0), 
                        function (b) {return (b>0)});
   dlt[0] = dlt[0] + std[1]*60000;
   std[0] = std[0] + dlt[1]*60000;
  }
else
  std = dlt = [0,-now.getTimezoneOffset()];


Вот что мы имеем в итоге исполнения этого кода. На выходе у нас получается два массива dlt и std. Первый содержит данные о точке перехода на летнее время, второй на стандартное. Первым элементом каждого массива идет timestamp точки перехода в локальном времени, второй смещенние относительно GMT после перехода. Если в временной зоне клиента нет перехода на летнее время, то первые элементы обоих массивов будут равны нулю, а вторые смещению временной зоны по GMT

Конечно по этим данным нельзя однозначно определить временную зону клиента, так как среди них много пересечений в настоящее время, но есть расхождение в прошлом. Тем не менее если использовать их для автоматической конвертации времени, то этого вполне достаточно.
Tags:
Hubs:
+4
Comments 10
Comments Comments 10

Articles