Come superare il problema del fuso orario in Magento?


8

Ho usato questo metodo per aggiungere il selettore di data e ora nel backend magento. Ora il tempo di input viene memorizzato correttamente nel mio database.

Il problema è che il fuso orario del mio negozio Magento è impostato sull'ora indiana standard (GMT + 05: 30), quindi il tempo mostrato in ADMIN GRID è il valore del tempo di input (che è in DataBase) + 05:30 ore.

  • vista phpmyadmin:

inserisci qui la descrizione dell'immagine

tempo nel database: 7:15 e 7:52

  • visualizzazione griglia admin magento:

inserisci qui la descrizione dell'immagine

tempo in amministrazione 12:45 pm e 13:22

Questo non mi disturba poiché il conto alla rovescia che visualizzo sul frontend assume il valore mostrato nella griglia di amministrazione. Sono felice. Ma quando si seleziona il selettore data e ora, mostra l'ora GMT, ovvero l'ora memorizzata nel database.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Pertanto, la persona che inserisce l'ora deve inserire un'ora che è 5:30 in anticipo all'ora prevista.

Risposte:


13

quando salvi la data aggiornata o la data di creazione, usa sempre gmt time Mage::getModel('core/date')->gmtDate()


Ciao @Marius Esiste un modo per aggiungere il tempo gmt nella griglia del prodotto in magento2?
Naveenbos,

1

Quindi, dopo aver trascorso quasi un giorno a combattere con lo stesso problema nella mia estensione, ho pensato di condividere la mia soluzione qui. Qualcosa da notare è che le mie entità non stanno utilizzando il sistema EAV, ogni entità ha la sua tabella piatta con una colonna per ogni attributo. La mia entità ha quattro attributi datetime: due dei quali sono compilati dall'input dell'utente ( open_date, close_date) e due dei quali sono popolati automaticamente dal codice sorgente ( create_date, close_date).

La classe modello dell'entità

Nella classe del modello dell'entità ho incluso quanto segue:

  1. Un modo per definire e recuperare quali attributi sono di tipo datetime e vengono popolati tramite i dati immessi dall'utente forniti nell'ora locale del negozio.
  2. Un metodo che converte solo questi campi dall'ora GMT all'ora locale del negozio (ne parleremo più avanti).
  3. Un metodo _beforeSave () che imposta gli attributi 'edit_date' e 'create_date' (che non sono popolati dall'input dell'utente) in GMT per me automaticamente al salvataggio.

Il codice sorgente:

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

L'azione save del controller di amministrazione dell'entità

Nel metodo saveAction del mio controller, ho utilizzato il metodo getDateFields () definito nella classe del modello per sapere quali attributi devo cambiare dall'ora locale del negozio (che era stata immessa dall'utente) all'ora GMT prima di salvare nella base di date. Nota che questo è solo uno snippit parziale del mio metodo di salvataggio:

....

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

....

Admin Form Block per la modifica dell'entità

A differenza del widget della griglia di amministrazione di Magento, che prevede valori datetime dalle raccolte da fornire in GMT, con l'intenzione di convertire questi valori nell'ora locale del negozio prima di visualizzare la pagina, il widget del modulo di amministrazione di Magento non segue questo comportamento. Il widget del modulo accetterà invece il valore datetime così com'è e lo visualizzerà senza regolare automaticamente l'ora. Pertanto, poiché i valori sono memorizzati nel database in GMT, dobbiamo prima convertire gli attributi datetime immessi dall'utente nell'ora locale del negozio prima di fornire tali dati al modulo. È qui che entra in gioco la nostra classe n. 2 su The Entity's Model Class .

Ecco una PORZIONE del metodo _prepareForm () della classe di blocco del mio modulo di amministrazione (che estende Mage_Adminhtml_Block_Widget_Form). Ho omesso la maggior parte della mia funzione, cercando di includere solo il minimo indispensabile per questa domanda e fornire comunque un metodo di classe valido:

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 maggior parte di ciò segue qualsiasi altro widget di modulo per Magento. Tuttavia, l'unica cosa chiave che è importante notare qui è che anziché chiamare $form->setValues($model->getData())chiamiamo $form->setValues($model->getAdminFormData()). Che, se esaminiamo il mio codice dal primo segmento di questa risposta, questo metodo richiede di convertire tutti gli attributi datetime, immessi dall'utente, dal GMT all'ora locale del negozio.

Risultato finale:

  1. Tutti i valori salvati nel DB nell'ora GMT.
  2. I valori immessi dall'utente vengono convertiti da GMT all'ora locale del negozio, prima di inviarlo per la modifica del modulo
  3. Admin Grid funziona come sempre, prendendo i valori GMT e convertendoli nell'ora locale del negozio prima di eseguire il rendering della griglia sulla pagina.

Spero che questo si dimostri una risorsa preziosa per aiutare qualcun altro là fuori un giorno. Vieni ora che lavori allo sviluppo front-end, tieni presente che i valori di datetime sono in GMT nel DB!


Questa risposta è davvero buona, ma la funzione getAdminFormData () non è nel tuo codice di esempio. Potresti modificare la risposta? Grazie!
Wouter,

@Wouter Buona cattura. Spiacente, "getAdminFormData ()" era un metodo personalizzato che si applicava solo alla mia estensione in quel momento. Penso che se ricordo correttamente che avevo bisogno di elaborare alcuni dei dati solo per i moduli di amministrazione. Per la maggior parte di tutti gli scenari $form->setValues($model->getData())dovrebbe semplicemente fare.
Darren Felton,

Ciao. Grazie per la buona risposta! Inoltre, la funzione getAdminFormData()può avere questa forma nella classe del modellopublic 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(); }
Dmitry Zar

-1

Puoi controllare il file

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

E commenta le stringhe successive

CalendarDateObject._LOCAL_TIMZEONE_OFFSET_SECONDS
CalendarDateObject._SERVER_TIMZEONE_SECONDS

Ciò dovrebbe indicare al widget di utilizzare le impostazioni del browser.


-1

Dovresti usare il metodo corretto quando aggiungi un campo data usando il file di installazione mysql in Spazio dei nomi> Modulo> 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();

1
Cuciture come questa non hanno nulla a che fare con la domanda.
Marius

Se conosci Magento, sapresti che lo script sopra genera l'HTML e JS corretti per il datepicker nel backend. Vedi altri esempi [ forum.emthemes.com/…
Richard Feraro l'

Esatto ... ma la domanda non ha nulla a che fare con l'aggiunta di un attributo datetime all'entità prodotto ... o forse hai ragione e devo imparare un po 'di Magento ( occhiolino occhiolino )
Marius

Il problema sopra è causato dal formato di visualizzazione non valido del datepicker perché lo mostra usando un offset diverso. L'aggiunta del codice riportato di seguito secondo lo script sopra assicurerà che la visualizzazione del datepicker sia sincronizzata con qualsiasi fuso orario sia impostato sul sito Web / negozio Magento. 'backend' => 'eav/entity_attribute_backend_datetime', // this fixes your issue
Richard Feraro,

Non posso discuterne, ma dove vedi nella domanda che ciò è legato ai prodotti? La mia scommessa è che si tratta di un'entità personalizzata (non EAV). Quindi addAttributenon ha potere qui.
Marius
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.