Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: nasyОтветов: 4

Я не знаю, как лучше всего сохранить метку времени в базе данных. Я хочу сохранить всю дату с часами, минутами и секундами, но она хранит только дату (например, 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;

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

  • А если вам нужно работать с разными часовыми поясами, прочтите документы meze 16.07.2012

phpsymfonytimestampdatetimedoctrine-orm

Ответы

Ответ 1 · рейтинг 12 · Gordon

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

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

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

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

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

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

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

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

Ответ 2 · рейтинг 11 · Mick

Чтобы сохранить дату создания без использования поведения доктрины 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');
    }

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

Ответ 3 · рейтинг 5 · thenetimp

Основываясь на ответе @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 функции, одну для создания одной для обновления, но это работает, поэтому я не вижу причин для дополнительного кода, когда он работает правильно.

Ответ 4 · рейтинг 4 · amdramdas

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

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы