Правильная реализация учёта летнего времени

zerkms

TDD infected
Команда форума
Правильная реализация учёта летнего времени

Таймзона пользователя хранится в виде "Asia/Vladivostok"

В пхп выставляется как ini_set('date.timezone', $timezone);

После коннекта с mysql сразу выставляется зона и там:

$this->query(Database::UPDATE, "SET time_zone='" . date('P') . "'", $this->_connection, false);

В итоге получаем, что в воскресенье 28 марта зона с +10 сменилась на +11, и все даты ранее 28 марта из базы, конечно же, поехали на час вперёд.

Есть ли какое-то элегантное решение, чтобы учитывать этот глупый час?

UPD: в базе всё хранится в mysql timestamp
 

mz

Новичок
отнимать час в пхп если текущая дата в daylight saving и дата из базы нет, чем не элегантно? ;)
 

@ndrey

Новичок
самое элегантное (имхо) работать относительно UTC-0 и даты в базе хранить в UTC-0
 

zerkms

TDD infected
Команда форума
@ndrey
ну храним. дальше что? как выводить?

mz
не элегантно тем, что не решение.
текущая дата (28 марта) в DST. дата от 27 марта нет. дата от 29 - да.
как что определить?

-~{}~ 29.03.10 03:26:

отнимать час в пхп если текущая дата в daylight saving и дата из базы нет
как определить, что дата из базы не в DST?
 

Fortop

Новичок
текущая дата (28 марта) в DST. дата от 27 марта нет. дата от 29 - да.
как что определить?
глянуть в мануал? [m]datetimezone[/m]
PHP:
$dt = new DateTimeZone('Europe/Kiev');
$ds = mktime(2,0,0,3,28,2009);
$de = mktime(4,0,0,3,28,2010);
var_dump($ds,$de);
var_dump($dt->getTransitions($ds,$de));
 

@ndrey

Новичок
zerkms
Привожу свой пример: у меня сервер находится в одной стране, пользователи в разных странах, т.е проблема часовых поясов для меня актуальна. Часовые смещения я не храню в базе, а c помощью js получаю от пользователя в переменную $tz. Местное время отдаю так:
date('d.m.Y H:i:s', time()+3600*$tz), в скриптах использую date_default_timezone_set('UTC').
 

zerkms

TDD infected
Команда форума
Код:
int(1238169600) int(1269709200)
Warning: DateTimeZone::getTransitions() expects exactly 0 parameters, 2 given in D:\server\www\index.php on line 7
bool(false)
даже хз как интерпретировать этот результат %) (5.2.12)

-~{}~ 29.03.10 03:44:

@ndrey
какой ужас. у меня даты уже в UTC в mysql и всю рутину за меня делает mysql.
 

Fortop

Новичок
zerkms
Версия?

array 
  0 => 
    array 
      'ts' => int 1238198400 
      'time' => string '2009-03-28T00:00:00+0000' (length=24) 
      'offset' => int 7200 
      'isdst' => boolean false 
      'abbr' => string 'EET' (length=3) 
  1 => 
    array 
      'ts' => int 1238288400 
      'time' => string '2009-03-29T01:00:00+0000' (length=24) 
      'offset' => int 10800 
      'isdst' => boolean true 
      'abbr' => string 'EEST' (length=4) 
  2 => 
    array 
      'ts' => int 1256432400 
      'time' => string '2009-10-25T01:00:00+0000' (length=24) 
      'offset' => int 7200 
      'isdst' => boolean false 
      'abbr' => string 'EET' (length=3) 
 

Fortop

Новичок
Нет, я конечно понимаю, а если дать ей ожидаемое число параметров? :)
 

zerkms

TDD infected
Команда форума
тогда получаем огромный массив из 119 элементов
Код:
  [118]=>
  array(5) {
    ["ts"]=>
    int(2140045200)
    ["time"]=>
    string(24) "2037-10-25T01:00:00+0000"
    ["offset"]=>
    int(7200)
    ["isdst"]=>
    bool(false)
    ["abbr"]=>
    string(3) "EET"
  }
примерно такого вот вида

-~{}~ 29.03.10 03:53:

Fortop
я кстати никак не могу понять, что за 3 элемента на твоём php 5.3 было получено. документация как всегда детальностью описания поражает.
 

Fortop

Новичок
даты когда были переводы времени в указанном промежутке

-~{}~ 28.03.10 19:56:

http://simpliest.co.cc/sample/date/dt.php

-~{}~ 28.03.10 19:57:

Т.е. дата после
Код:
 [61]=>
  array(5) {
    ["ts"]=>
    int(1269738000)
    ["time"]=>
    string(24) "2010-03-28T01:00:00+0000"
    ["offset"]=>
    int(10800)
    ["isdst"]=>
    bool(true)
    ["abbr"]=>
    string(4) "EEST"
в DST
 

zerkms

TDD infected
Команда форума
даты когда были переводы времени в указанном промежутке
ну тогда результаты неправильные, потому как время переводится с 2 на 3 (в марте) или с 3 на 2 (в октябре)

хотя да - это уже лучше, чем ничего. т.е. тупо придётся при выводе даты корректировать, мде %)
 

Fortop

Новичок
Вот только хоть убейте меня, но часы у меня перевелись в 3 часа ночи. А не в 1 час.

Поэтому данное время "2010-03-28T01:00:00+0000" судя по всему(искать пруфлинк мне лень) задано в UTC и это надо учитывать.
 

zerkms

TDD infected
Команда форума
мерси, угу. будем значит обходить этот адский массив при каждом выводе даты и считать.... чудесненько %)

-~{}~ 29.03.10 04:00:

Fortop
часы в россии и переводятся с 2х на 3. так что правильно у тебя перевелось.

Поэтому данное время "2010-03-28T01:00:00+0000" судя по всему(искать пруфлинк мне лень) задано в UTC и это надо учитывать.
тогда у меня это 11 утра что ли? :))
 

zerkms

TDD infected
Команда форума
а, не, всё окейно:

$dt = new DateTimeZone('Asia/Vladivostok');

Код:
  [61]=>
  array(5) {
    ["ts"]=>
    int(1269705600)
    ["time"]=>
    string(24) "2010-03-27T16:00:00+0000"
    ["offset"]=>
    int(39600)
    ["isdst"]=>
    bool(true)
    ["abbr"]=>
    string(5) "VLAST"
  }
-~{}~ 29.03.10 04:04:

PHP:
echo date('d-m-Y H:i:s', strtotime('2010-03-27T15:00:00+0000'));
echo '<br/>';
echo date('d-m-Y H:i:s', strtotime('2010-03-27T16:00:00+0000'));
Код:
28-03-2010 01:00:00
28-03-2010 03:00:00
угу, ляпота. спасибо, панацея найдена, правда с обходом дурацкого массива :)
 
Сверху