8

I used this method, to add date and time picker in magento backend. Now the input time is getting stored to my database correctly.

The problem is my magento store's timezone is set to Indian Standard time (GMT+05:30), so the time shown in ADMIN GRID, is the input time value (which is in DataBase) + 05:30 Hrs.

  • phpmyadmin view:

enter image description here

time in database: 7:15 am and 7:52 am

  • magento admin grid view:

enter image description here

time in admin 12:45 pm and 1:22 pm

This doesn't bother me as the countdown timer I display on frontend take the value shown in admin grid. I'm happy. But when selecting the time in date time picker, it shows the GMT, i.e. time stored in Database.

enter image description here enter image description here

So, the person, who enter the time input should enter a time which is 5:30 hrs in advance to the intended time.

0

4 Answers 4

13

when you save updated date or created date,always use gmt time Mage::getModel('core/date')->gmtDate()

1
  • Hi @Marius Is there any way to add gmt time in the product grid in magento2?
    – Naveenbos
    Oct 26, 2017 at 13:28
3

So after spending nearly a day fighting with this same problem in my own extension, I thought I'd share my solution here. Something to note is that my entities are not utilizing the EAV system, each entity has it's own flat table with a column for each attribute. My entity has four datetime attributes-- two of which are populated from user input (open_date,close_date), and two of which are populated automatically by the source code (create_date,close_date).

The Entity's Model Class

In the entity's model class I included the following:

  1. A way to define and fetch what attributes are of the type datetime and are populated via user inputted data supplied in the store's local time.
  2. A method which converts just these fields from GMT time to the store's local time (more on this later).
  3. A _beforeSave() method which sets the 'edit_date' and 'create_date' attributes (which are not populated via user input) in GMT for me automatically on save.

The source code:

/**
 * 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 of the Entity's Admin Controller

In my controller's saveAction method, I utilized the getDateFields() method defined in the model class to know which attributes I need to change from the store's local time (which was user inputted) to GMT time prior to saving to the datebase. Note that this is only a partial snippit of my save method:

....

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

....

The Admin Form Block for editing the Entity

Unlike the Magento's admin grid widget, which expects datetime values from collections to be supplied in GMT, with intentions to convert these values to the store's local time prior to displaying the the page, Magento's admin form widget does not follow this behavior. Instead the form widget will accept the datetime value as is, and display it without automatically adjusting the time. Therefore, since values are stored in the database in GMT, we must first convert our user entered datetime attributes to the store's local time before supplying that data to the form. This is where our #2 on The Entity's Model Class comes into play.

Here is a PORTION of the _prepareForm() method of my admin form's block class (which extends Mage_Adminhtml_Block_Widget_Form). I've omitted the majority of my function, trying to only include the bare minimum that is relevant to this question, and still provide a valid class method:

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

Most of this is follows any other form widget for Magento. However the one key thing that is important to note here is that rather than calling $form->setValues($model->getData()) we call $form->setValues($model->getAdminFormData()). Which, if we review my code from the first segment of this answer, this method takes of converting all datetime attributes, that are user inputted, from GMT to the store's local time.

End Result:

  1. All values saved into DB in GMT time.
  2. User inputted values are converted from GMT to store's local time, prior to giving it to edit form
  3. Admin Grid works as it always has, taking in GMT values and converting to the store's local time prior to rendering the grid on the page.

Hope this proves as a valuable resource to help someone else out there someday. Come time that you work on front-end development, keep in mind that the datetime values are in GMT in the DB!

3
  • This answer is really good, but the function getAdminFormData() is not in your example code. Could you edit the answer? Thanks!
    – Wouter
    Jan 18, 2016 at 12:14
  • @Wouter Good catch. Sorry the "getAdminFormData()" was a custom method that applied to just my extension at the time. I think if I remember correctly that I needed to process some of the data just for the admin forms. For most all scenarios simply $form->setValues($model->getData()) should do. Jan 18, 2016 at 16:38
  • Hello. Thanks for good answer! In addition, function getAdminFormData() can have this form in model class 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(); }
    – Dmitry Zar
    Dec 6, 2017 at 7:28
-1

You can check file

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

And comment next strings

CalendarDateObject._LOCAL_TIMZEONE_OFFSET_SECONDS
CalendarDateObject._SERVER_TIMZEONE_SECONDS

That should tell the widget to use browser settings.

0
-1

You should use the proper method when adding a date field using the mysql setup file under Namespace > Module > sql > module_setup > mysql4-install/upgrade-x.x.x.php:

<?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();
8
  • 1
    Seams like this has nothing to do with the question.
    – Marius
    Apr 10, 2014 at 11:09
  • If you know Magento, you would know that the script above generates the proper HTML and JS for the datepicker in the backend. See other examples [forum.emthemes.com/… Apr 11, 2014 at 6:54
  • Exactly...but the question has nothing to to with adding a datetime attribute to the product entity...or maybe you are right and I have to learn some Magento (wink wink)
    – Marius
    Apr 11, 2014 at 6:56
  • The issue above is caused by the invalid display format of the datepicker because it shows it using a different offset. Adding the code below as per the script above will make sure that the display of the datepicker is in sync with whatever timezone is set on the Magento website/store. 'backend' => 'eav/entity_attribute_backend_datetime', // this fixes your issue Apr 11, 2014 at 7:01
  • I can't argue with that, but where in the question do you see that this is related to products? My bet is that this is a custom (Non EAV) entity. So addAttribute has no power here.
    – Marius
    Apr 11, 2014 at 7:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.