Symfony2 datetime лучший способ хранить временные метки?

Я не знаю, как лучше всего сохранить метку времени в базе данных. Я хочу сохранить всю дату с часами, минутами и секундами, но она хранит только дату (например, 2012-07-14), и я хочу сохранить 2012-07-14 HH: MM: SS. Я использую объект dateTime. Вот код:

В контроллере:

$user->setCreated(new \DateTime());

В объекте:

/**
 * @var date $created
 *
 * @ORM\Column(name="created", type="date")
 */
private $created;

Не лучше ли хранить дату и время отдельно в базе данных? или лучше хранить все вместе как ГГГГ-ММ-ДД ЧЧ: ММ: СС? Затем мне придется сравнить даты и вычислить оставшееся время, так что это важно для упрощения операций в дальнейшем. Так что ты думаешь ? кто-нибудь может мне помочь?


person nasy    schedule 16.07.2012    source источник
comment
А если вам нужно работать с разными часовыми поясами, прочтите документы   -  person meze    schedule 16.07.2012


Ответы (4)


Лучший способ сохранить отметку времени в базе данных, очевидно, - использовать столбец отметки времени, если ваша база данных поддерживает этот тип. И поскольку вы можете настроить этот столбец на автоматическое обновление при создании, вам даже не нужно предоставлять для него установщик.

Существует расширение поведения Timestampable для Doctrine 2, которое делает именно это со стороны пользователя, поскольку Что ж:

Поведение с отметкой времени автоматизирует обновление полей даты в ваших объектах или документах. Он работает через аннотации и может обновлять поля при создании, обновлении или даже при изменении значения определенного свойства.

Возможности:

  • Автоматическое обновление поля предопределенной даты при создании, обновлении и даже при изменении свойств записи
  • Поддержка ORM и ODM с использованием одного и того же слушателя
  • Специальные аннотации для свойств, интерфейс не требуется
  • Может реагировать на изменение определенного свойства или отношения к определенному значению
  • Может быть вложен в другое поведение
  • Поддержка аннотаций, Yaml и Xml для расширений

При таком поведении все, что вам нужно сделать, это изменить аннотацию на

/**
 * @var datetime $created
 *
 * @Gedmo\Timestampable(on="create")
 * @ORM\Column(type="datetime")
 */
private $created;

Тогда вам не нужно вызывать setCreated в коде. Поле будет установлено автоматически при первом создании объекта.

person Gordon    schedule 16.07.2012
comment
Timestampable не очень полезен, если вы обрабатываете разные часовые пояса. - person meze; 16.07.2012
comment
Хорошо, попробую, вариант отлично смотрится. Спасибо! - person nasy; 16.07.2012
comment
@meze нигде в вопросе не упоминаются разные часовые пояса, и я бы сказал, что часовые пояса не имеют отношения к созданным полям. - person Gordon; 16.07.2012
comment
@Gordon +1 за этот классный пост. Я попробовал ваш метод сравнить с тем, который использовал я (см. Ниже). Я получаю очень похожие, но все же разные времена (Ваш метод: 2012-07-25 00:07:29; Мой метод: 2012-07-25 00:00:29) Какова причина этого? А какое время точнее? Спасибо - person Mick; 24.07.2012
comment
@ Sydney_o9, я не знаю причины. разница в семь часов, что заставляет меня предположить, что часовой пояс не установлен должным образом ни в одном из двух подходов. - person Gordon; 24.07.2012
comment
Всего 7 минут ... не 7 часов :-) - person Mick; 24.07.2012
comment
@ Sydney_o9, правда, плохо. К сожалению, я до сих пор не знаю. - person Gordon; 24.07.2012

Чтобы сохранить дату создания без использования поведения доктрины Timestampable, вы также можете использовать LifeCycle Callbacks, добавив аннотацию @ORM\HasLifecycleCallbacks при объявлении класса. Вот что будет работать в вашем случае для хранения в базе данных ГГГГ-ММ-ДД ЧЧ: ММ: СС.

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table(name="yourTable")
 */
class Nasy
{

    /**
    * @ORM\Column(name="created", type="string", length=255)
    */

    private $created;
    /**
     * @ORM\PrePersist
     */
    public function doStuffOnPrePersist()
    {
        $this->created = date('Y-m-d H:i:s');
    }

Наконец, если у вас есть проблема с часовым поясом, вы можете установить часовой пояс в сеансе с помощью прослушивателя событий при входе в систему. Мэтт Дролете отлично поработал в своем блоге здесь. Вы, вероятно, всегда будете хранить время в часовом поясе, в котором находится ваш сервер. Затем вы используете часовой пояс, установленный в сеансе, чтобы отображать правильное время для пользователя. Удачи.

person Mick    schedule 24.07.2012
comment
Проблема с вашим кодом заключается в том, что вы храните его в строке, что делает невозможным выполнение операций sql с ним, при этом сохраняя эффективность. - person thenetimp; 31.10.2012
comment
У вас ошибка в вашем формате: месяцы против минут. Правильный формат: ... дата ('Y-m-d H: i: s'); - person qualbeen; 29.10.2013
comment
Если ваша собственность относится к типу datetime, а не string, вы должны использовать: $this->created = new \DateTime(); - person Nate; 31.03.2016

Основываясь на ответе @Pratt, я сделал это. У меня есть 2 поля в моих объектах: одно для создания и одно для изменения.

/**
* @ORM\Column(type="datetime")
 */
protected $created_at;

/**
* @ORM\Column(type="datetime")
 */
protected $modified_at;

А затем, используя аннотацию, я вызываю это в prePersist и preUpdate.

/**
 * @ORM\PrePersist
 * @ORM\PreUpdate
 */
public function updatedTimestamps()
{
    $this->setModifiedAt(new \DateTime(date('Y-m-d H:i:s')));

    if($this->getCreatedAt() == null)
    {
        $this->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
    }
}

Функцию можно разбить на 2 функции, одну для создания одной для обновления, но это работает, поэтому я не вижу причин для дополнительного кода, когда он работает правильно.

person thenetimp    schedule 31.10.2012

Вы можете использовать @Version так:

/**
 * @var date $created
 *
 * @ORM\Column(name="created", type="datetime")
 * @ORM\Version
 */
private $created;

Это будет работать только с типом datetime.

person amdramdas    schedule 18.03.2014
comment
Мне оно нравится больше, чем просто скачивать расширение Gedmo ... Но что именно делает Версия? - person Yann Chabot; 26.06.2015