Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: DateTime() Сравнение и интервалы
Форумы портала PHP.SU » » Вопросы новичков » DateTime() Сравнение и интервалы

Страниц (2): [1] 2 »
 

1. TuX560 - 19 Января, 2016 - 09:20:04 - перейти к сообщению
Доброго времени суток, вопрос глупый, но четкого ответа как это реализовать я так и не нашел.

Собственно задача:
Полученное время из бд(хранится в timestamp) сравнить с текущим и если оно больше n дней - выполнить определенные действия.

Текущее решение:
PHP:
скопировать код в буфер обмена
  1. new DateTime()->diff(new DateTime(created_at))->d > n


Возможно ли сделать это как-то иначе(быстрее. лучше)? Мысли были в сторону интервалов, но там так же придется преобразовывать и создавать объекты, а так же есть проблема с приведенным выше - в логах ругается на неустановленный timezone и отказывается работать, как это исправить? В данный момент использую задание на прямую вида new DateTime('now',new DateTimeZone('UTC')). Работает, но в случаи несовпадения tz на сервере с указанным получаем перевод текущего времени и как следствие не верный результат
2. KingStar - 19 Января, 2016 - 09:56:19 - перейти к сообщению
3. TuX560 - 19 Января, 2016 - 11:17:00 - перейти к сообщению
Благодарю, а что если на сервере будет другая tz? Есть вариант чтобы получить текущее время сервера без перевода с учетом tz?
4. Мелкий - 19 Января, 2016 - 16:46:21 - перейти к сообщению
TuX560 пишет:
текущее время сервера без перевода с учетом tz

А теперь задумайтесь, какой бред вы написали.
Место и пространство - одно и то же. И не только в физике. Время дня не имеет значения без часового пояса. Кстати, даже с таймзоной зависит от конкретной даты, час может меняться.

Волевым решением вы можете выбрать какую-то одну таймзону и от неё прыгать. Например, всё всегда считать в UTC. Соответственно и все настройки конфигурировать и сохранять в UTC.

TuX560 пишет:
в случаи несовпадения tz на сервере с указанным получаем перевод текущего времени и как следствие не верный результат

Верный результат. Осталось только осмыслить, для какой таймзоны.
5. TuX560 - 20 Января, 2016 - 09:41:14 - перейти к сообщению
Мелкий, Абсолютно с Вами согласен, но ситуация в другом, вопрос в том что бы без костылей получить текущее системное время для сравнения с временем из бд(не припомню что бы в тех же плюсах приходилось учазывать timezone для этого, да и time() тоже отлично работает без tz).

Я был бы не против если бы он переводил и системное и полученное из бд время в данную tz в противном случаи получается следующее: время в бд вставляется автоматически значением по умолчанию (CURRENT_TIMESTAMP), а при получении текущего времени для нахождении разности происходит смещение, что дает неверный результат между данными величинами.

upd. откуда мне знать какая tz будет выставлена у сервера? Идея все в UTC - идеальна, вот только как я понял MySQL вставляет текущее системное время не глядя на tz
6. andrewkard - 20 Января, 2016 - 11:02:30 - перейти к сообщению
TuX560 пишет:
вот только как я понял MySQL вставляет текущее системное время не глядя на tz

Цитата:

NOW()
Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current time zone.

Как и CURRENT_*, CURTIME()
7. TuX560 - 20 Января, 2016 - 15:20:31 - перейти к сообщению
andrewkard пишет:

Цитата:

NOW()
Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current time zone.

Как и CURRENT_*, CURTIME()

Разве я не тоже самое написал? ему пофиг на tz, он вставляет время в текущем часовом поясе, или я не прав? Как следствие время в БД хранится в неизвестной tz, и как результат я не знаю в какую tz приводить текущий DateTime (кроме костыльного метода привязанного к *nix системам для определения системной tz ничего не встречал), или как получить время в системной tz.
8. andrewkard - 20 Января, 2016 - 15:49:14 - перейти к сообщению
TuX560 пишет:
время в текущем часовом поясе

в котором находится сервер. Если это известно, то далее дело техники.
9. Мелкий - 20 Января, 2016 - 16:01:50 - перейти к сообщению
TuX560 пишет:
не припомню что бы в тех же плюсах приходилось учазывать timezone для этого

Угу, так и запишем, раньше работали в рамках только одной таймзоны.

std::time - UNIX-time, это UTC0 всегда
std::localtime - текущая таймзона пользователя, от имени которого запущено приложение.
std::gmtime - соответственно, структура даты для UTC0
Как считаются другие таймзоны - честно не помню.

TuX560 пишет:
да и time() тоже отлично работает без tz).

Ага. Потому что UTC0 всегда. unixtime же.
Различие date, strftime с одной стороны и gmdate, gmstrftime в другой. Первые при обработке таймштампа смотрят на локальную таймзону date_default_timezone (не помню, как в ini названа), вторые - только UTC0.

TuX560 пишет:
время в бд вставляется автоматически значением по умолчанию

Так и базе скажите, в какой вы таймзоне хотите воспринимать время. В mysql системная переменная time_zone.
10. andrewkard - 20 Января, 2016 - 16:10:41 - перейти к сообщению
andrewkard пишет:
в котором находится сервер.

Хотя не все так однозначно Улыбка
http://dev[dot]mysql[dot]com/doc/refman/[dot][dot][dot]one-support[dot]html
(Добавление)


Понравился коммент в тему Улыбка


Цитата:

Set your server's clock to UTC. No really.

If you can do it, do do it.

One of the biggest headaches is "cron" jobs etc, running in local time zone, this means that some cron jobs will get missed once a year, and all the rest run at a different time GMT for half the year (I'm assuming you're in a time zone which has daylight saving time here).

MySQL has time zone support, but it's crazy and messed up. Don't use it if you don't have to. Just set your server's clock to UTC and time will start working how it should.

I know that changing the server clock is a major change for any managed system, and you may have a large number of servers and services which could be affected, but please, try to do it anyway. The QA work may be significant, but try.

http://stackoverflow[dot]com/questio[dot][dot][dot]unctions-use-utc
11. TuX560 - 21 Января, 2016 - 09:25:58 - перейти к сообщению
Благодарю, теперь наконец все встало на свои места)
andrewkard пишет:
в котором находится сервер. Если это известно, то далее дело техники.
Речь как раз о неизвестном, в данный момент нет никакого сервера(есть свой локальный для разработки), и в какой tz будет реальный - понятия не имею.

Мелкий пишет:
Угу, так и запишем, раньше работали в рамках только одной таймзоны.
Вы абсолютно правы, тк работать в UTC намного проще и в большинстве случаев достаточно)

Мелкий пишет:
Так и базе скажите, в какой вы таймзоне хотите воспринимать время. В mysql системная переменная time_zone.
Получается тоже не хорошо, но похоже так и придется. Не хорошо потому что если нет доступа к конфигурации mysql придется при каждом соединении отправлять запрос на установку данной переменной(или я ошибаюсь?) так же возникает вопрос: любой ли пользователь может это сделать(нужны ли дополнительные права)?

andrewkard пишет:
http://dev[dot]mysql[dot]com/doc/refman/[dot][dot][dot]one-support[dot]html
Благодарю, получается после каждого соединения с БД(в случаи невозможности изменения конфига) отправлять запрос SET time_zone = timezone или есть возможность задать это на этапе соединения используя mysqli(пока бегло пробежался не нашел, пойду еще почитаю)?

ЗЫ: Какое счастье что триггеров с датой нет и не предвидится
12. Мелкий - 21 Января, 2016 - 12:02:26 - перейти к сообщению
TuX560 пишет:
любой ли пользователь может это сделать(нужны ли дополнительные права)?

Сессионную - любой.
13. TuX560 - 21 Января, 2016 - 13:48:02 - перейти к сообщению
Мелкий пишет:
Сессионную - любой.

Спасибо, но в ходе раскопок возникли различные варианты решения:
1. задать значение поля по умолчанию как UTC_TIMESTAMP;
2. Как я понял хранит он все равно в UTC а при запросе конвертирует в соответствии с сессионной tz поэтому мы можем конвертировать сами во запросе: SELECT CONVERT_TZ(created_at, @@session.time_zone, '+00:00');
3. поменять сессионную tz запросом $mysqli->query("SET time_zone = +00:00");

Возможно существуют и другие(при отсутствии прав на изменение конфигов mysql и задание глобальной tz) поэтому вопрос как будет лучше?
14. Мелкий - 21 Января, 2016 - 14:02:49 - перейти к сообщению
поля timestamp - да, mysql хранит в UTC0 и конвертирует к таймзоне time_zone при обращении.
поля datetime - что записали, то будет прочитано вне зависимости от таймзоны.
15. TuX560 - 21 Января, 2016 - 15:58:39 - перейти к сообщению
И все же, как лучше поступить? в php без костылей системную tz не получить, как и время в текущей tz, следовательно получаем в UTC. по MySQL вариантам 1 - не нравится тем что похож на извращение хранить не верное время, 2 - не нравится тем что необходим для каждого запроса, а 3ий - необходим для каждого соединения.

Собственно немного поясню почему меня так волнует лишний запрос при каждом соединении с БД: сервис высоконагруженный и если можно обойтись без лишнего запроса к БД или решить данную проблему как-то иначе - был бы рад услышать данные советы.

 

Powered by ExBB FM 1.0 RC1