Magentoのタイムゾーンの問題を解決する方法は?


8

このメソッドを使用し、magentoバックエンドに日時ピッカーを追加しました。これで、入力時間がデータベースに正しく保存されます。

問題は、私のマジェントストアのタイムゾーンがインド標準時(GMT + 05:30)に設定されているため、ADMIN GRIDに表示される時間は、(データベースにある)入力時間値+ 05:30時間です。

  • phpmyadminビュー:

ここに画像の説明を入力してください

データベース内の時間:7:15 amと7:52 am

  • magento管理グリッドビュー:

ここに画像の説明を入力してください

管理者の時間:午後12:45および午後1:22

フロントエンドに表示するカウントダウンタイマーが管理グリッドに表示される値を取るので、これは気になりません。私は満足しています。ただし、日付時刻ピッカーで時刻を選択すると、GMT、つまりデータベースに保存されている時刻が表示されます。

ここに画像の説明を入力してください ここに画像の説明を入力してください

したがって、時間入力を入力する人は、予定されている時間の5:30時間前の時間を入力する必要があります。

回答:


13

更新日または作成日を保存するときは、常にgmt時間を使用してください Mage::getModel('core/date')->gmtDate()


こんにちは@Marius magento2の製品グリッドにgmt時間を追加する方法はありますか?
Naveenbos 2017年

1

したがって、自分の拡張機能でこの同じ問題との戦いにほぼ1日費やした後、私は自分の解決策をここで共有したいと思いました。注目すべきことは、私のエンティティはEAVシステムを利用していないことです。各エンティティには、各属性の列を持つ独自のフラットテーブルがあります。私のエンティティには4つの日時属性があります。そのうち2つはユーザー入力から入力され(open_dateclose_date)、2つはソースコードによって自動的に入力されます(create_dateclose_date)。

エンティティのモデルクラス

エンティティのモデルクラスに、以下を含めました。

  1. どの属性がタイプ日時であり、ストアのローカル時間で提供されるユーザー入力データを介して入力されるかを定義およびフェッチする方法。
  2. これらのフィールドのみをGMT時間からストアのローカル時間に変換するメソッド(これについては後で詳しく説明します)。
  3. 保存時に自動的にGMTで'edit_date'および 'create_date'属性(ユーザー入力を介して入力されない)を設定する_beforeSave()メソッド。

ソースコード:

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

コントローラーのsaveActionメソッドで、モデルクラスで定義されたgetDateFields()メソッドを利用して、ストアのローカル時間(ユーザーが入力したもの)からGMT時間に変更してからデータベースに保存する必要がある属性を確認しました。これは私の保存メソッドの一部にすぎないことに注意してください。

....

$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の管理フォームウィジェットはこの動作を行いません。代わりに、フォームウィジェットは日時の値をそのまま受け入れ、時刻を自動的に調整せずに表示します。したがって、値はデータベースにGMTで格納されるため、ユーザーが入力した日時属性をストアのローカル時間に変換してから、そのデータをフォームに提供する必要があります。これが、エンティティのモデルクラスの#2の出番です。

以下は、私の管理フォームのブロッククラス(Mage_Adminhtml_Block_Widget_Formを拡張)の_prepareForm()メソッドの一部です。私は関数の大部分を省略し、この質問に関連する最小限の要素のみを含め、有効なクラスメソッドを提供しようとしています。

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の他のフォームウィジェットに従います。ただし、ここで注意すべき重要な点の1つは、を呼び出すので$form->setValues($model->getData())はなく、を呼び出すこと$form->setValues($model->getAdminFormData())です。この回答の最初のセグメントからコードを確認すると、このメソッドは、ユーザー入力のすべての日時属性をGMTからストアのローカル時間に変換します。

最終結果:

  1. GMT時間でDBに保存されたすべての値。
  2. ユーザーが入力した値は、編集フォームに渡す前に、GMTから店舗の現地時間に変換されます。
  3. 管理グリッドは従来どおり機能し、ページにグリッドをレンダリングする前にGMT値を取り込み、ストアのローカル時間に変換します。

これがいつか他の誰かを助けるための貴重なリソースとして証明されることを願っています。フロントエンドの開発に取り掛かるときは、日時の値がDBのGMTであることを覚えておいてください。


この答えは本当に良いですが、関数getAdminFormData()はサンプルコードにはありません。回答を編集していただけませんか?ありがとう!
Wouter

@Wouter良いキャッチ。申し訳ありませんが、「getAdminFormData()」は、当時の拡張機能だけに適用されたカスタムメソッドでした。私が正しく覚えていれば、管理フォームだけのためにいくつかのデータを処理する必要があったと思います。ほとんどすべてのシナリオで、単に$form->setValues($model->getData())行う必要があります。
ダレンフェルトン2016年

こんにちは。良い答えをありがとう!さらに、関数getAdminFormData()はこの形式をモデルクラスで持つことができますpublic 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

ファイルを確認できます

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

そして次の文字列にコメント

CalendarDateObject._LOCAL_TIMZEONE_OFFSET_SECONDS
CalendarDateObject._SERVER_TIMZEONE_SECONDS

これにより、ウィジェットにブラウザ設定を使用するように指示する必要があります。


-1

名前空間>モジュール> sql> module_setup> mysql4-install / upgrade-xxxphpの下のmysqlセットアップファイルを使用して日付フィールドを追加するときは、適切な方法を使用する必要があります。

<?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
このような継ぎ目は問題とは関係ありません。
マリウス

Magentoを知っている場合は、上記のスクリプトがバックエンドの日付ピッカーに適切なHTMLとJSを生成することがわかります。参照してください。他の例[ forum.emthemes.com/...
リチャードFeraro

正確に...しかし、質問は製品エンティティに日時属性を追加することとは何の関係もありません...または多分あなたは正しいと私はいくつかのMagento(wink wink
マリウス

上記の問題は、異なるオフセットを使用して表示するため、日付ピッカーの無効な表示形式が原因です。上記のスクリプトに従って以下のコードを追加すると、日付ピッカーの表示がMagentoのWebサイト/ストアで設定されているタイムゾーンと確実に同期します。 'backend' => 'eav/entity_attribute_backend_datetime', // this fixes your issue
Richard Feraro 14

私はそれについて議論することはできませんが、質問のどこでこれが製品に関連していると思いますか?私の賭けは、これがカスタム(非EAV)エンティティであるということです。だからここにaddAttributeは力がありません。
マリウス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.