Làm thế nào để khắc phục vấn đề múi giờ trong Magento?


8

Tôi đã sử dụng phương pháp này , để thêm công cụ chọn ngày và giờ trong phụ trợ magento. Bây giờ thời gian đầu vào đang được lưu trữ vào cơ sở dữ liệu của tôi một cách chính xác.

Vấn đề là múi giờ của cửa hàng magento của tôi được đặt thành giờ chuẩn Ấn Độ (GMT + 05: 30), vì vậy thời gian hiển thị trong ADMIN GRID, là giá trị thời gian đầu vào (trong DataBase) + 05:30 Hrs.

  • Chế độ xem phpmyadmin:

nhập mô tả hình ảnh ở đây

thời gian trong cơ sở dữ liệu: 7:15 sáng và 7:51 sáng

  • xem lưới quản trị magento:

nhập mô tả hình ảnh ở đây

thời gian trong quản trị 12:45 tối và 1:22 chiều

Điều này không làm phiền tôi vì đồng hồ đếm ngược tôi hiển thị trên frontend lấy giá trị hiển thị trong lưới quản trị. Tôi đang hạnh phúc. Nhưng khi chọn công cụ chọn thời gian trong ngày, nó sẽ hiển thị GMT, tức là thời gian được lưu trữ trong Cơ sở dữ liệu.

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Vì vậy, người nhập thời gian đầu vào nên nhập thời gian trước 5:30 giờ so với thời gian dự định.

Câu trả lời:


13

Khi bạn lưu ngày cập nhật hoặc ngày tạo, luôn luôn sử dụng thời gian gmt Mage::getModel('core/date')->gmtDate()


Xin chào @Marius Có cách nào để thêm thời gian gmt vào lưới sản phẩm trong magento2 không?
Naveenbos

1

Vì vậy, sau khi dành gần một ngày để chiến đấu với vấn đề tương tự này trong phần mở rộng của riêng tôi, tôi nghĩ tôi sẽ chia sẻ giải pháp của mình ở đây. Một điều cần lưu ý là các thực thể của tôi không sử dụng hệ thống EAV, mỗi thực thể có bảng phẳng riêng với một cột cho mỗi thuộc tính. Thực thể của tôi có bốn thuộc tính datetime-- hai trong số đó được điền từ đầu vào của người dùng ( open_date, close_date) và hai trong số đó được nhập tự động bởi mã nguồn ( create_date, close_date).

Lớp mẫu của thực thể

Trong lớp mô hình của thực thể tôi bao gồm:

  1. Một cách để xác định và tìm nạp các thuộc tính của loại thời gian được điền thông qua dữ liệu nhập vào của người dùng được cung cấp trong giờ địa phương của cửa hàng.
  2. Một phương thức chuyển đổi chỉ các trường này từ giờ GMT sang giờ địa phương của cửa hàng (nhiều hơn về điều này sau).
  3. Phương thức _b BeforeSave () tự động đặt các thuộc tính 'edit_date' và 'create_date' ( không được điền thông qua đầu vào của người dùng) trong GMT cho tôi tự động lưu.

Mã nguồn:

/**
 * 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 của Trình điều khiển quản trị của thực thể

Trong phương thức saveAction của bộ điều khiển, tôi đã sử dụng phương thức getDateFields () được xác định trong lớp mô hình để biết thuộc tính nào tôi cần thay đổi từ giờ địa phương của cửa hàng (được người dùng nhập vào) vào giờ GMT trước khi lưu vào cơ sở ngày. Lưu ý rằng đây chỉ là một phần của phương thức lưu của tôi:

....

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

....

Khối biểu mẫu quản trị để chỉnh sửa thực thể

Không giống như tiện ích lưới quản trị của Magento, dự kiến ​​các giá trị thời gian từ các bộ sưu tập sẽ được cung cấp trong GMT, với ý định chuyển đổi các giá trị này thành giờ địa phương của cửa hàng trước khi hiển thị trang, tiện ích biểu mẫu quản trị viên của Magento không tuân theo hành vi này. Thay vào đó, tiện ích biểu mẫu sẽ chấp nhận giá trị datetime như hiện tại và hiển thị nó mà không tự động điều chỉnh thời gian. Do đó, vì các giá trị được lưu trữ trong cơ sở dữ liệu theo GMT, trước tiên chúng tôi phải chuyển đổi các thuộc tính datetime của người dùng thành thời gian cục bộ của cửa hàng trước khi cung cấp dữ liệu đó cho biểu mẫu. Đây là nơi số 2 của chúng tôi trên Lớp Người mẫu của Thực thể phát huy tác dụng.

Đây là một phần của phương thức _prepareForm () của lớp khối của quản trị viên của tôi (mở rộng Mage_Adminhtml_Block_Widget_Form). Tôi đã bỏ qua phần lớn chức năng của mình, cố gắng chỉ bao gồm mức tối thiểu trần có liên quan đến câu hỏi này và vẫn cung cấp một phương thức lớp hợp lệ:

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

Hầu hết điều này tuân theo bất kỳ tiện ích biểu mẫu nào khác cho Magento. Tuy nhiên, một điều quan trọng cần lưu ý ở đây là thay vì gọi $form->setValues($model->getData())chúng tôi gọi $form->setValues($model->getAdminFormData()). Mà, nếu chúng tôi xem xét mã của tôi từ phân đoạn đầu tiên của câu trả lời này, phương thức này sẽ chuyển đổi tất cả các thuộc tính datetime, được người dùng nhập vào, từ GMT sang giờ địa phương của cửa hàng.

Kết quả cuối cùng:

  1. Tất cả các giá trị được lưu vào DB trong thời gian GMT.
  2. Các giá trị được nhập của người dùng được chuyển đổi từ GMT sang giờ địa phương của cửa hàng, trước khi đưa nó vào biểu mẫu chỉnh sửa
  3. Lưới quản trị hoạt động như mọi khi, lấy các giá trị GMT và chuyển đổi sang giờ địa phương của cửa hàng trước khi hiển thị lưới trên trang.

Hy vọng điều này chứng tỏ là một nguồn tài nguyên quý giá để giúp đỡ người khác ngoài kia một ngày nào đó. Hãy đến lúc bạn làm việc về phát triển front-end, hãy nhớ rằng các giá trị datetime nằm trong GMT trong DB!


Câu trả lời này thực sự tốt, nhưng hàm getAdminFormData () không có trong mã ví dụ của bạn. Bạn có thể chỉnh sửa câu trả lời? Cảm ơn!
Wouter

@Wouter Bắt tốt. Xin lỗi, "getAdminFormData ()" là một phương thức tùy chỉnh chỉ áp dụng cho tiện ích mở rộng của tôi tại thời điểm đó. Tôi nghĩ rằng nếu tôi nhớ chính xác rằng tôi cần xử lý một số dữ liệu chỉ dành cho biểu mẫu quản trị viên. Đối với hầu hết các kịch bản đơn giản $form->setValues($model->getData())nên làm.
Darren Felton

Xin chào. Cảm ơn câu trả lời tốt! Ngoài ra, hàm getAdminFormData()có thể có dạng này trong lớp mô hìnhpublic 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

Bạn có thể kiểm tra tập tin

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

Và bình luận chuỗi tiếp theo

CalendarDateObject._LOCAL_TIMZEONE_OFFSET_SECONDS
CalendarDateObject._SERVER_TIMZEONE_SECONDS

Điều đó sẽ cho các widget sử dụng cài đặt trình duyệt.


-1

Bạn nên sử dụng phương pháp thích hợp khi thêm trường ngày bằng tệp thiết lập mysql trong Namespace> Module> sql> module_setup> mysql4-install / nâng cấp-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
Các đường may như thế này không liên quan gì đến câu hỏi.
Marius

Nếu bạn biết Magento, bạn sẽ biết rằng tập lệnh ở trên tạo ra HTML và JS thích hợp cho công cụ hẹn hò trong phần phụ trợ. Xem các ví dụ khác [ forum.emtheme.com/ Từ
Richard Feraro

Chính xác ... nhưng câu hỏi không liên quan gì đến việc thêm thuộc tính datetime vào thực thể sản phẩm ... hoặc có thể bạn đúng và tôi phải học một số Magento ( nháy mắt )
Marius

Vấn đề ở trên là do định dạng hiển thị không hợp lệ của datepicker vì nó hiển thị nó bằng cách sử dụng một phần bù khác. Thêm mã bên dưới theo tập lệnh ở trên sẽ đảm bảo rằng màn hình hiển thị của bộ đo thời gian đồng bộ với bất kỳ múi giờ nào được đặt trên trang web / cửa hàng Magento. 'backend' => 'eav/entity_attribute_backend_datetime', // this fixes your issue
Richard Feraro

Tôi không thể tranh luận với điều đó, nhưng bạn thấy điều này có liên quan đến sản phẩm ở đâu? Đặt cược của tôi là đây là một thực thể tùy chỉnh (Non EAV). Vì vậy, addAttributekhông có quyền lực ở đây.
Marius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.