¿Cómo superar el problema de la zona horaria en Magento?

8

Usé este método , para agregar el selector de fecha y hora en el backend de magento. Ahora el tiempo de entrada se está almacenando en mi base de datos correctamente.

El problema es que la zona horaria de mi tienda magento está configurada en la hora estándar de la India (GMT + 05: 30), por lo que la hora que se muestra en ADMIN GRID es el valor de la hora de entrada (que se encuentra en DataBase) + 05:30 Hrs.

  • Vista phpmyadmin:

ingrese la descripción de la imagen aquí

hora en la base de datos: 7:15 a.m. y 7:52 a.m.

  • Vista de cuadrícula de administrador de magento:

ingrese la descripción de la imagen aquí

hora en admin 12:45 pm y 1:22 pm

Esto no me molesta, ya que el temporizador de cuenta regresiva que muestro en la interfaz toma el valor que se muestra en la cuadrícula de administración. Estoy feliz. Pero al seleccionar la hora en el selector de fecha y hora, muestra el GMT, es decir, la hora almacenada en la base de datos.

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Por lo tanto, la persona que ingresa la entrada de tiempo debe ingresar una hora con 5:30 horas de anticipación a la hora prevista.

Shathish
fuente

Respuestas:

13

cuando guarde la fecha actualizada o la fecha de creación, use siempre la hora GMT Mage::getModel('core/date')->gmtDate()

Franco
fuente
Hola @ Mario ¿Hay alguna manera de agregar tiempo GMT en la cuadrícula del producto en magento2?
Naveenbos
1

Entonces, después de pasar casi un día luchando con este mismo problema en mi propia extensión, pensé en compartir mi solución aquí. Algo a tener en cuenta es que mis entidades no están utilizando el sistema EAV, cada entidad tiene su propia tabla plana con una columna para cada atributo. Mi entidad tiene cuatro atributos de fecha y hora, dos de los cuales se rellenan a partir de la entrada del usuario ( open_date, close_date) y dos de los cuales se rellenan automáticamente con el código fuente ( create_date, close_date).

La clase de modelo de la entidad

En la clase de modelo de la entidad incluí lo siguiente:

  1. Una forma de definir y buscar qué atributos son del tipo datetime y se completan a través de los datos ingresados ​​por el usuario suministrados en la hora local de la tienda.
  2. Un método que convierte solo estos campos de la hora GMT a la hora local de la tienda (más sobre esto más adelante).
  3. Un método _beforeSave () que establece los atributos 'edit_date' y 'create_date' (que no se completan a través de la entrada del usuario) en GMT para mí automáticamente al guardar.

El código fuente:

/**
 * 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;
}

La acción saveAction del controlador administrativo de la entidad

En el método saveAction de mi controlador, utilicé el método getDateFields () definido en la clase de modelo para saber qué atributos necesito cambiar de la hora local de la tienda (que fue ingresada por el usuario) a la hora GMT antes de guardar en la base de datos. Tenga en cuenta que esto es solo un fragmento parcial de mi método de guardar:

....

$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();

....

El bloque de formulario de administrador para editar la entidad

A diferencia del widget de cuadrícula de administración de Magento, que espera que los valores de fecha y hora de las colecciones se suministren en GMT, con la intención de convertir estos valores a la hora local de la tienda antes de mostrar la página, el widget de formulario de administración de Magento no sigue este comportamiento. En cambio, el widget de formulario aceptará el valor de fecha y hora como es, y lo mostrará sin ajustar automáticamente la hora. Por lo tanto, dado que los valores se almacenan en la base de datos en GMT, primero debemos convertir nuestros atributos de fecha y hora ingresados ​​por el usuario a la hora local de la tienda antes de suministrar esos datos al formulario. Aquí es donde entra en juego nuestro # 2 en la clase de modelo de la entidad .

Aquí hay una PORCIÓN del método _prepareForm () de la clase de bloque de mi formulario de administrador (que extiende Mage_Adminhtml_Block_Widget_Form). He omitido la mayoría de mi función, tratando de incluir solo el mínimo básico que es relevante para esta pregunta, y aún así proporcionar un método de clase válido:

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();
}

La mayor parte de esto sigue cualquier otro widget de formulario para Magento. Sin embargo, lo importante que es importante tener en cuenta aquí es que en lugar de llamar $form->setValues($model->getData()), llamamos $form->setValues($model->getAdminFormData()). Lo cual, si revisamos mi código desde el primer segmento de esta respuesta, este método requiere la conversión de todos los atributos de fecha y hora, que son ingresados ​​por el usuario, de GMT a la hora local de la tienda.

Resultado final:

  1. Todos los valores guardados en DB en tiempo GMT.
  2. Los valores ingresados ​​por el usuario se convierten de GMT a la hora local de la tienda, antes de darle el formulario de edición
  3. Admin Grid funciona como siempre, tomando los valores GMT y convirtiéndolos a la hora local de la tienda antes de mostrar la grilla en la página.

Espero que esto sea un recurso valioso para ayudar a alguien más algún día. Cuando llegue el momento de trabajar en el desarrollo front-end, tenga en cuenta que los valores de fecha y hora están en GMT en el DB.

Darren Felton
fuente
Esta respuesta es realmente buena, pero la función getAdminFormData () no está en su código de ejemplo. ¿Podrías editar la respuesta? ¡Gracias!
Wouter
@ Agua Buena captura. Lo sentimos, "getAdminFormData ()" era un método personalizado que se aplicaba solo a mi extensión en ese momento. Creo que si recuerdo correctamente que necesitaba procesar algunos de los datos solo para los formularios de administración. Para la mayoría de los escenarios, simplemente $form->setValues($model->getData())debería hacerlo.
Darren Felton
Hola. Gracias por la buena respuesta! Además, la función getAdminFormData()puede tener este formulario en la clase de modelopublic function getAdminFormData() { $dateAr = $this->getDateFields(); foreach ($dateAr as $date) { $loc_date = Mage::getModel('core/date')->date('Y-m-d H:i:s',($this->getData($date))); $this->setData($date,$loc_date); } return $this->getData(); }
ZMage
-1

Puedes consultar el archivo

app/design/adminhtml/default/default/template/page/js/calendar.phtml

Y comentar las siguientes cadenas

CalendarDateObject._LOCAL_TIMZEONE_OFFSET_SECONDS
CalendarDateObject._SERVER_TIMZEONE_SECONDS

Eso debería indicarle al widget que use la configuración del navegador.

vovikha
fuente
-1

Debe usar el método adecuado al agregar un campo de fecha usando el archivo de configuración de mysql en Espacio de nombres> Módulo> sql> module_setup> mysql4-install / upgrade-xxxphp :

<?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();
Richard Feraro
fuente
1
Costuras como esta no tienen nada que ver con la pregunta.
Marius
Si conoce Magento, sabrá que la secuencia de comandos anterior genera el HTML y JS adecuados para el selector de fechas en el back-end. Ver otros ejemplos [ forum.emthemes.com/…
Richard Feraro
Exactamente ... pero la pregunta no tiene nada que ver con agregar un atributo de fecha y hora a la entidad del producto ... o tal vez tengas razón y tengo que aprender algo de Magento ( guiño )
Marius
El problema anterior es causado por el formato de visualización no válido del selector de fecha porque lo muestra usando un desplazamiento diferente. Al agregar el siguiente código según el script anterior, se asegurará de que la visualización del selector de fecha esté sincronizada con la zona horaria establecida en el sitio web / tienda de Magento. 'backend' => 'eav/entity_attribute_backend_datetime', // this fixes your issue
Richard Feraro
No puedo discutir eso, pero ¿en qué parte de la pregunta ves que esto está relacionado con los productos? Mi apuesta es que esta es una entidad personalizada (no EAV). Entonces addAttributeno tiene poder aquí.
Marius