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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: DateTime() Сравнение и интервалы

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
TuX560
Отправлено: 19 Января, 2016 - 09:20:04
Post Id


Гость


Покинул форум
Сообщений всего: 114
Дата рег-ции: Дек. 2015  


Помог: 3 раз(а)




Доброго времени суток, вопрос глупый, но четкого ответа как это реализовать я так и не нашел.

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

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


Возможно ли сделать это как-то иначе(быстрее. лучше)? Мысли были в сторону интервалов, но там так же придется преобразовывать и создавать объекты, а так же есть проблема с приведенным выше - в логах ругается на неустановленный timezone и отказывается работать, как это исправить? В данный момент использую задание на прямую вида new DateTime('now',new DateTimeZone('UTC')). Работает, но в случаи несовпадения tz на сервере с указанным получаем перевод текущего времени и как следствие не верный результат
 
 Top
KingStar
Отправлено: 19 Января, 2016 - 09:56:19
Post Id



Участник


Покинул форум
Сообщений всего: 1889
Дата рег-ции: Авг. 2011  
Откуда: Беларусь


Помог: 69 раз(а)






-----
То что программа работает, не означает что она написана правильно!
 
 Top
TuX560
Отправлено: 19 Января, 2016 - 11:17:00
Post Id


Гость


Покинул форум
Сообщений всего: 114
Дата рег-ции: Дек. 2015  


Помог: 3 раз(а)




Благодарю, а что если на сервере будет другая tz? Есть вариант чтобы получить текущее время сервера без перевода с учетом tz?
 
 Top
Мелкий Супермодератор
Отправлено: 19 Января, 2016 - 16:46:21
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




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

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

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

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

Верный результат. Осталось только осмыслить, для какой таймзоны.


-----
PostgreSQL DBA
 
 Top
TuX560
Отправлено: 20 Января, 2016 - 09:41:14
Post Id


Гость


Покинул форум
Сообщений всего: 114
Дата рег-ции: Дек. 2015  


Помог: 3 раз(а)




Мелкий, Абсолютно с Вами согласен, но ситуация в другом, вопрос в том что бы без костылей получить текущее системное время для сравнения с временем из бд(не припомню что бы в тех же плюсах приходилось учазывать timezone для этого, да и time() тоже отлично работает без tz).

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

upd. откуда мне знать какая tz будет выставлена у сервера? Идея все в UTC - идеальна, вот только как я понял MySQL вставляет текущее системное время не глядя на tz

(Отредактировано автором: 20 Января, 2016 - 09:48:47)

 
 Top
andrewkard
Отправлено: 20 Января, 2016 - 11:02:30
Post Id


Участник


Покинул форум
Сообщений всего: 1372
Дата рег-ции: Нояб. 2014  


Помог: 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()
 
 Top
TuX560
Отправлено: 20 Января, 2016 - 15:20:31
Post Id


Гость


Покинул форум
Сообщений всего: 114
Дата рег-ции: Дек. 2015  


Помог: 3 раз(а)




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.
 
 Top
andrewkard
Отправлено: 20 Января, 2016 - 15:49:14
Post Id


Участник


Покинул форум
Сообщений всего: 1372
Дата рег-ции: Нояб. 2014  


Помог: 30 раз(а)




TuX560 пишет:
время в текущем часовом поясе

в котором находится сервер. Если это известно, то далее дело техники.
 
 Top
Мелкий Супермодератор
Отправлено: 20 Января, 2016 - 16:01:50
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




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.


-----
PostgreSQL DBA
 
 Top
andrewkard
Отправлено: 20 Января, 2016 - 16:10:41
Post Id


Участник


Покинул форум
Сообщений всего: 1372
Дата рег-ции: Нояб. 2014  


Помог: 30 раз(а)




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
 
 Top
TuX560
Отправлено: 21 Января, 2016 - 09:25:58
Post Id


Гость


Покинул форум
Сообщений всего: 114
Дата рег-ции: Дек. 2015  


Помог: 3 раз(а)




Благодарю, теперь наконец все встало на свои места)
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(пока бегло пробежался не нашел, пойду еще почитаю)?

ЗЫ: Какое счастье что триггеров с датой нет и не предвидится

(Отредактировано автором: 21 Января, 2016 - 09:27:29)

 
 Top
Мелкий Супермодератор
Отправлено: 21 Января, 2016 - 12:02:26
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




TuX560 пишет:
любой ли пользователь может это сделать(нужны ли дополнительные права)?

Сессионную - любой.


-----
PostgreSQL DBA
 
 Top
TuX560
Отправлено: 21 Января, 2016 - 13:48:02
Post Id


Гость


Покинул форум
Сообщений всего: 114
Дата рег-ции: Дек. 2015  


Помог: 3 раз(а)




Мелкий пишет:
Сессионную - любой.

Спасибо, но в ходе раскопок возникли различные варианты решения:
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) поэтому вопрос как будет лучше?
 
 Top
Мелкий Супермодератор
Отправлено: 21 Января, 2016 - 14:02:49
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




поля timestamp - да, mysql хранит в UTC0 и конвертирует к таймзоне time_zone при обращении.
поля datetime - что записали, то будет прочитано вне зависимости от таймзоны.


-----
PostgreSQL DBA
 
 Top
TuX560
Отправлено: 21 Января, 2016 - 15:58:39
Post Id


Гость


Покинул форум
Сообщений всего: 114
Дата рег-ции: Дек. 2015  


Помог: 3 раз(а)




И все же, как лучше поступить? в php без костылей системную tz не получить, как и время в текущей tz, следовательно получаем в UTC. по MySQL вариантам 1 - не нравится тем что похож на извращение хранить не верное время, 2 - не нравится тем что необходим для каждого запроса, а 3ий - необходим для каждого соединения.

Собственно немного поясню почему меня так волнует лишний запрос при каждом соединении с БД: сервис высоконагруженный и если можно обойтись без лишнего запроса к БД или решить данную проблему как-то иначе - был бы рад услышать данные советы.
 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB