Bagaimana cara mengatasi masalah zona waktu di Magento?

8

Saya menggunakan metode ini , untuk menambahkan pemilih tanggal dan waktu di backend magento. Sekarang waktu input disimpan ke basis data saya dengan benar.

Masalahnya adalah zona waktu toko magento saya diatur ke waktu Standar India (GMT + 05: 30), jadi waktu yang ditunjukkan dalam ADMIN GRID, adalah nilai waktu input (yang ada di DataBase) + 05:30 Jam.

  • tampilan phpmyadmin:

masukkan deskripsi gambar di sini

waktu dalam database: 7:15 dan 7:52 pagi

  • tampilan kotak admin magento:

masukkan deskripsi gambar di sini

waktu di admin 12:45 dan 13:22

Ini tidak mengganggu saya karena penghitung waktu mundur yang saya tampilkan di frontend mengambil nilai yang ditampilkan di kisi admin. Saya senang. Tetapi ketika memilih waktu dalam pemilih waktu tanggal, itu menunjukkan GMT, yaitu waktu yang disimpan dalam Database.

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Jadi, orang yang memasukkan input waktu harus memasukkan waktu 5:30 jam di muka ke waktu yang dimaksud.

Shathish
sumber

Jawaban:

13

saat Anda menyimpan tanggal yang diperbarui atau tanggal yang dibuat, selalu gunakan waktu gmt Mage::getModel('core/date')->gmtDate()

jujur
sumber
Hai @Marius Apakah ada cara untuk menambah waktu gmt di kotak produk di magento2?
Naveenbos
1

Jadi setelah menghabiskan hampir satu hari berjuang dengan masalah yang sama dalam ekstensi saya sendiri, saya pikir saya akan membagikan solusi saya di sini. Sesuatu yang perlu diperhatikan adalah bahwa entitas saya tidak menggunakan sistem EAV, setiap entitas memiliki tabel sendiri dengan kolom untuk setiap atribut. Entitas saya memiliki empat atribut datetime - dua di antaranya diisi dari input pengguna ( open_date, close_date), dan dua di antaranya diisi secara otomatis oleh kode sumber ( create_date, close_date).

Kelas Model Entitas

Di kelas model entitas saya sertakan yang berikut:

  1. Cara untuk mendefinisikan dan mengambil atribut apa dari tipe datetime dan diisi melalui data yang dimasukkan pengguna yang disediakan dalam waktu lokal toko.
  2. Metode yang mengonversi hanya bidang ini dari waktu GMT ke waktu lokal toko (lebih lanjut tentang ini nanti).
  3. Metode _beforeSave () yang menetapkan atribut 'edit_date' dan 'create_date' (yang tidak diisi melalui input pengguna) dalam GMT untuk saya secara otomatis disimpan.

Kode sumber:

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

The saveAction dari Pengontrol Admin Entitas

Dalam metode saveAction milik pengontrol, saya menggunakan metode getDateFields () yang didefinisikan dalam kelas model untuk mengetahui atribut mana yang perlu saya ubah dari waktu lokal toko (yang dimasukkan pengguna) ke waktu GMT sebelum menyimpan ke basis data. Perhatikan bahwa ini hanya sebagian potongan dari metode simpan saya:

....

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

....

Blok Formulir Admin untuk mengedit Entitas

Tidak seperti widget kisi admin Magento, yang mengharapkan nilai datetime dari koleksi yang akan disediakan dalam GMT, dengan niat untuk mengkonversi nilai-nilai ini ke waktu lokal toko sebelum menampilkan halaman, widget formulir admin Magento tidak mengikuti perilaku ini. Sebagai gantinya, widget bentuk akan menerima nilai datetime apa adanya, dan menampilkannya tanpa secara otomatis menyesuaikan waktu. Oleh karena itu, karena nilai disimpan dalam database dalam GMT, pertama-tama kita harus mengonversi atribut datetime yang dimasukkan pengguna ke waktu lokal toko sebelum memasok data tersebut ke formulir. Di sinilah # 2 kami di Kelas Model Entity ikut bermain.

Berikut ini adalah PORTION dari metode _prepareForm () dari kelas blok formulir admin saya (yang meluas Mage_Adminhtml_Block_Widget_Form). Saya telah menghilangkan sebagian besar fungsi saya, mencoba untuk hanya memasukkan minimum yang relevan dengan pertanyaan ini, dan masih memberikan metode kelas yang valid:

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

Sebagian besar dari ini mengikuti bentuk widget lainnya untuk Magento. Namun satu hal kunci yang penting untuk dicatat di sini adalah bahwa alih-alih menelepon, $form->setValues($model->getData())kita memanggil $form->setValues($model->getAdminFormData()). Yang mana, jika kami meninjau kode saya dari segmen pertama dari jawaban ini, metode ini akan mengkonversi semua atribut datetime, yang dimasukkan pengguna, dari GMT ke waktu lokal toko.

Hasil akhir:

  1. Semua nilai disimpan ke DB dalam waktu GMT.
  2. Nilai yang dimasukkan pengguna dikonversi dari GMT ke waktu lokal store, sebelum memberikannya untuk diedit
  3. Admin Grid berfungsi seperti biasanya, mengambil nilai GMT dan mengonversi ke waktu lokal toko sebelum merender kisi pada halaman.

Semoga ini terbukti sebagai sumber daya berharga untuk membantu orang lain di luar sana suatu hari nanti. Saat Anda bekerja pada pengembangan front-end, perlu diingat bahwa nilai-nilai datetime dalam GMT dalam DB!

Darren Felton
sumber
Jawaban ini sangat bagus, tetapi fungsi getAdminFormData () tidak ada dalam kode contoh Anda. Bisakah Anda mengedit jawabannya? Terima kasih!
Wouter
@Wouter Tangkapan yang bagus. Maaf "getAdminFormData ()" adalah metode khusus yang hanya diterapkan pada ekstensi saya saat itu. Saya pikir jika saya ingat dengan benar bahwa saya perlu memproses beberapa data hanya untuk formulir admin. Untuk sebagian besar semua skenario $form->setValues($model->getData())harus dilakukan.
Darren Felton
Halo. Terima kasih atas jawaban yang bagus! Selain itu, fungsi getAdminFormData()dapat memiliki formulir ini di kelas modelpublic 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

Anda dapat memeriksa file

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

Dan komentar string berikutnya

CalendarDateObject._LOCAL_TIMZEONE_OFFSET_SECONDS
CalendarDateObject._SERVER_TIMZEONE_SECONDS

Itu akan memberi tahu widget untuk menggunakan pengaturan browser.

vovikha
sumber
-1

Anda harus menggunakan metode yang tepat saat menambahkan bidang tanggal menggunakan file setup mysql di Namespace> Module> 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
sumber
1
Jahitan seperti ini tidak ada hubungannya dengan pertanyaan.
Marius
Jika Anda tahu Magento, Anda akan tahu bahwa skrip di atas menghasilkan HTML dan JS yang tepat untuk datepicker di backend. Lihat contoh lain [ forum.emthemes.com/…
Richard Feraro
Tepat ... tetapi pertanyaannya tidak ada hubungannya dengan menambahkan atribut datetime ke entitas produk ... atau mungkin Anda benar dan saya harus belajar beberapa Magento ( mengedipkan mata )
Marius
Masalah di atas disebabkan oleh format tampilan yang tidak valid dari datepicker karena menunjukkannya menggunakan offset yang berbeda. Menambahkan kode di bawah sesuai skrip di atas akan memastikan bahwa tampilan datepicker sinkron dengan zona waktu apa pun yang ditetapkan di situs web / toko Magento. 'backend' => 'eav/entity_attribute_backend_datetime', // this fixes your issue
Richard Feraro
Saya tidak bisa berdebat dengan itu, tetapi di mana dalam pertanyaan Anda melihat bahwa ini terkait dengan produk? Taruhan saya adalah bahwa ini adalah entitas kustom (Non EAV). Jadi addAttributetidak punya kekuatan di sini.
Marius