Как преодолеть проблему часового пояса в Magento?
Я использовал этот метод , чтобы добавить средство выбора даты и времени в серверную часть magento. Теперь время ввода правильно сохраняется в моей базе данных.
Проблема в том, что часовой пояс моего магазина magento установлен на индийское стандартное время (GMT+05:30), поэтому время, показанное в ТАБЛИЦЕ АДМИНИСТРАТОРА, является входным значением времени (которое находится в базе данных) +05:30 часов.
- представление phpmyadmin:
Время в базе данных: 7:15 утра и 7:52 ам
- представление сетки администратора magento:
Время в администраторе 12:45 вечера и 1:22 вечера
Это меня не беспокоит, так как таймер обратного отсчета, который я показываю на интерфейсе, принимает значение, показанное в таблице администратора. Я счастлив. Но при выборе времени в средстве выбора даты и времени оно показывает GMT, то есть время, хранящееся в базе данных.
Таким образом, человек, который вводит ввод времени, должен ввести время, которое составляет 5:30 часов заранее, чтобы предполагаемое время.
4 answers
При сохранении обновленной или созданной даты всегда используйте время по Гринвичу Mage::getModel('core/date')->gmtDate()
Итак, потратив почти целый день на борьбу с этой же проблемой в моем собственном расширении, я решил поделиться своим решением здесь. Следует отметить, что мои сущности не используют систему EAV, у каждой сущности есть своя собственная плоская таблица со столбцом для каждого атрибута. Моя сущность имеет четыре атрибута даты и времени, два из которых заполняются из пользовательского ввода (open_date
,close_date
), и два из которых автоматически заполняются исходным кодом (create_date
,close_date
).
Модель сущности Класс
В класс модели сущности я включил следующее:
- Способ определения и извлечения атрибутов типа datetime и заполняются с помощью введенных пользователем данных, предоставленных по местному времени магазина.
- Метод, который преобразует только эти поля из времени GMT в местное время магазина (подробнее об этом позже).
- Метод _beforeSave(), который устанавливает атрибуты "edit_date" и "create_date" (которые являются нет заполняется через пользовательский ввод) в GMT для меня автоматически при сохранении.
Исходный код:
/**
* Model's datetime attributes that are populated with user data supplied
* in the store's local time.
*
* @var array
*/
protected $_dateFields = array(
'open_date',
'close_date',
);
/**
* Return the model's datetime attributes that are populated with user
* data supplied in the store's local time.
*
* @return array
*/
public function getDateFields()
{
return $this->_dateFields;
}
/**
* (non-PHPdoc)
* @see Mage_Core_Model_Abstract::_beforeSave()
*/
protected function _beforeSave()
{
parent::_beforeSave();
$date = Mage::getModel('core/date')->gmtDate();
if (!$this->getId()) {
$this->setData('create_date', $date);
}
$this->setData('edit_date', $date);
return $this;
}
Действие сохранения Контроллера администратора Сущности
В методе Saveaction моего контроллера я использовал метод getDateFields(), определенный в классе модели, чтобы узнать, какие атрибуты мне нужно изменить с местного времени магазина (которое было введено пользователем) на время по Гринвичу до сохранения в базе данных. Обратите внимание, что это только частичное фрагмент моего метода сохранения:
....
$data = $this->getRequest()->getPost()
// Convert user input time from the store's local time to GMT time
$dateFields = $model->getDateFields();
if (is_array($dateFields) && count($dateFields)) {
$data = $this->_filterDateTime($data, $dateFields);
$store_timezone = new DateTimeZone(Mage::getStoreConfig('general/locale/timezone'));
$gmt_timezone = new DateTimeZone('Europe/London');
foreach ($dateFields as $key) if (isset($data[$key])) {
$dateTime = new DateTime($data[$key], $store_timezone);
$dateTime->setTimezone($gmt_timezone);
$data[$key] = $dateTime->format('Y-m-d H:i:s');
}
}
$model->addData($data);
try {
$model->save();
....
Блок формы Администратора для редактирования сущности
В отличие от виджета сетки администратора Magento, который ожидает, что значения даты и времени из коллекций будут предоставлены в GMT, с намерением преобразовать эти значения в местное время магазина до отображения страницы, виджет формы администратора Magento не следует этому поведению. Вместо этого виджет формы примет значение даты и времени как есть и отобразит его без автоматической настройки время. Поэтому, поскольку значения хранятся в базе данных по Гринвичу, мы должны сначала преобразовать введенные пользователем атрибуты даты и времени в местное время магазина, прежде чем вводить эти данные в форму. Именно здесь вступает в игру наш №2 по Классу модели Сущности.
Вот ЧАСТЬ метода _prepareform() класса блока моей формы администратора (который расширяет Mage_Adminhtml_Block_Widget_Form). Я опустил большую часть своей функции, пытаясь включить только тот минимум, который имеет отношение к этому вопросу и по-прежнему предоставляет допустимый метод класса:
protected function _prepareForm()
{
$form = new Varien_Data_Form();
$model = Mage::registry('YOUR_MODEL_CLASS');
$date_format = Mage::app()->getLocale()->getDateTimeFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM);
$time_zone = $this->__('Time Zone: %s', Mage::getStoreConfig('general/locale/timezone'));
$calendar_img = $this->getSkinUrl('images/grid-cal.gif');
$fieldset = $form->addFieldset('base_fieldset', array('legend'=> $this->__('General Information')));
$fieldset->addField('open_date', 'datetime', array(
'name' => 'open_date',
'label' => $this->__('Open Date'),
'title' => $this->__('Open Date'),
'time' => 'true',
'image' => $calendar_img,
'format' => $date_format,
'style' => 'width:160px',
'required' => true,
'note' => $time_zone
));
$fieldset->addField('close_date', 'datetime', array(
'name' => 'close_date',
'label' => $this->__('Close Date'),
'title' => $this->__('Close Date'),
'time' => 'true',
'image' => $calendar_img,
'format' => $date_format,
'style' => 'width:160px',
'required' => true,
'note' => $time_zone
));
if ($model->getId()) {
$form->setValues($model->getAdminFormData());
}
$this->setForm($form);
return parent::_prepareForm();
}
Большая часть этого следует за любым другим виджетом формы для Magento. Однако здесь важно отметить одну ключевую вещь: вместо вызова $form->setValues($model->getData())
мы вызываем $form->setValues($model->getAdminFormData())
. Что, если мы рассмотрим мой код из первого сегмента этого ответа, этот метод использует преобразование всех атрибутов даты и времени, введенных пользователем, с GMT по местному времени магазина.
Конечный результат:
- Все значения сохранено в БД по времени GMT.
- Введенные пользователем значения преобразуются из GMT в местное время магазина, прежде чем передавать их в форму редактирования
- Сетка администратора работает так же, как и всегда, принимая значения GMT и преобразуя их в местное время магазина перед отображением сетки на странице.
Надеюсь, что это окажется ценным ресурсом, который когда-нибудь поможет кому-то еще. Когда вы начнете работать над интерфейсной разработкой, имейте в виду, что значения даты и времени указаны по Гринвичу в ДБ!
Вы можете проверить файл
app/design/adminhtml/default/default/template/page/js/calendar.phtml
И прокомментируйте следующие строки
CalendarDateObject._LOCAL_TIMZEONE_OFFSET_SECONDS
CalendarDateObject._SERVER_TIMZEONE_SECONDS
Это должно указывать виджету использовать настройки браузера.
Вы должны использовать правильный метод при добавлении поля даты с помощью установочного файла mysql в разделе Пространство имен > Модуль > sql > module_setup> mysql4-install/upgrade-x.x.x.php:
<?php
$installer = $this;
$installer->startSetup();
$installer->addAttribute(
'catalog_product',
'custom_datetime',
array(
'label' => 'Custom DateTime', // modify this
'required' => false,
'type' => 'datetime',
'input' => 'date',
'backend' => 'eav/entity_attribute_backend_datetime', // this fixes your issue
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'visible_on_front' => 1,
'position' => 1,
'time' => true,
'group' => 'General', // modify this
'sort_order' => 23, // modify this
)
);
$installer->endSetup();