3

I'm trying to set a time in the product special price to/from dates (i.e., special price from 3/20/2013 11am EST to 4/20/2013 10:59am EST), but I cannot get a time to show up or save.

When I enter a time in the admin (for example, 03/20/2013 11:00:00), it always shows up with 00:00:00 in the database. I don't really need to update the admin to allow showing the time in the calendar widget; rather I just need it to save if I put in a time.

3

I think this is a serious Magento bug. special_price_from has a backend model Mage_Catalog_Model_Product_Attribute_Backend_Startdate (that extends Mage_Eav_Model_Entity_Attribute_Backend_Datetime) and special_price_to has the backend model Mage_Eav_Model_Entity_Attribute_Backend_Datetime.

Now each time you save one of these attributes this method is called Mage_Eav_Model_Entity_Attribute_Backend_Datetime::beforeSave($object). And because the calendar does not send the date in an international format you end up in this section of the code in the method Mage_Eav_Model_Entity_Attribute_Backend_Datetime::formatDate($date):

$date = Mage::app()->getLocale()->date($date,
               Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT),
               null, false
            );

This strips the time part. A work around would be to change this piece of code to

$date = Mage::app()->getLocale()->date($date,
               Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT. ' HH:mm:ss'),
               null, false
            );

(copy the file in local folder. There is no other way to override this class because there are other classes extendng it) This will save the time also in your database, but there is an other problem. Even if the time is saved correctly in the database when editing the product the date still appears without the time and on any other save the time ill disappear again.

For this you need to modify the renderer for the datetime attributes.

And here is where I got stuck. Maybe you have an idea on how to do it. If I find one I will edit my answer and describe it.

In conclusion it's not that straight forward to do what you want and it a serious issue that should be raised to Magento.

EDIT

Ok I found this link. I think it involves core changes and I don't recommend it. But you can copy the files you need to modify to the local folder.

  • 1
    thanks for the reply! question though: we are saving these special prices outside of the admin (it's a site that is using a different frontend and admin), so as long as i don't edit the date in the magento admin, i should be ok with just using a local version of Mage_Eav_Model_Entity_Attribute_Backend_Datetime? – Laura Mar 21 '13 at 16:49
  • 1
    in theory it should work but test it very carefully. – Marius Mar 21 '13 at 16:54
3

Whew, lost nearly a week on this issue!! But this post pointed to the solution, that is, after having discovered that you could simply go in the table 'eav_attribute' and change the 'frontend_input' value from 'date' to 'datetime' and have the calendar widget in the backend also to display the hour and minute (and the input field to accept the value).

But then Magento didn't save the time of day and so...

I copied the file app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Datetime.php in my local folder (app/code/local/Mage/Eav/Model/Entity/Attribute/Backend) and modified it as follows:

around line 44 substitute to:

try {
  $value = $this->formatDate($object->getData($attributeName), $attributeFrontendInput);

this:

try {
  $attributeFrontendInput = $this->getAttribute()->getFrontendInput();
  $value = $this->formatDate($object->getData($attributeName), $attributeFrontendInput);

(here we get the attribute frontend_input model, that is 'date' or 'datetime' or whatever and then pass it to the formatDate function)

Then in the formatDate function later in the code to accept the new second parameter add to the parameter list in the function header the variable $feInput

public function formatDate($date, $feInput)

and then around line 87 substitute to:

$date = Mage::app()->getLocale()->date($date,
   Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT),
    null, false
);

this:

if ($feInput == 'datetime') {
    $date = Mage::app()->getLocale()->date($date,
        Mage::app()->getLocale()->getDateTimeFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT),
        null, false
    );
} else {
    $date = Mage::app()->getLocale()->date($date,
        Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT),
        null, false
    );
}

Here we test the $feInput variable and use the getDateTimeFormat function in the Magento core codebase if the input model equals 'datetime'.

I hope someone maybe could spare a few working days with this. Thanks to all the guys and girls on Stack Exchange!!

EDIT:

this is just for being able to input and store correctly datetime values from Magento backend. Having the datetime values correctly checked and processed in the various points in which they are processed in the frontend is another story...

0

In addition to his friend Marius posted to return the html value in hours is necessary to make the following change:

Change this:

    $html = sprintf(
        '<input name="%s" id="%s" value="%s" %s style="width:110px !important;" />'
        .' <img src="%s" alt="" class="v-middle" id="%s_trig" title="%s" style="%s" />',
        $this->getName(), $this->getHtmlId(), $this->_escape($this->getValue()), $this->serialize($this->getHtmlAttributes()),
        $this->getImage(), $this->getHtmlId(), 'Select Date', ($this->getDisabled() ? 'display:none;' : '')
    );

that is why:

    $html = sprintf(
        '<input name="%s" id="%s" value="%s" %s style="width:110px !important;" />'
        .' <img src="%s" alt="" class="v-middle" id="%s_trig" title="%s" style="%s" />',
        $this->getName(), $this->getHtmlId(), $this->_escape($this->getValue($outputFormat)), $this->serialize($this->getHtmlAttributes()),
        $this->getImage(), $this->getHtmlId(), 'Select Date', ($this->getDisabled() ? 'display:none;' : '')
    );

That is, change $outputFormat the getValue function.

This worked well. Hope this helps.

  • Which file I will change the above changes...? – VijayS91 Jan 13 '16 at 17:22
0

Just spent 5 hour to work with this (with combination of Marius answer)

File: \lib\Varien\Data\Form\Element\Data.php

For my locale only, change it to yourself add function:

public function getRawMysqlDateFormat ($value) {
    if (empty($this->_value)) {
        return null;
    }
    $new_date = explode(" ", $value);
    //2017年4月1日 下午4:16:16
    $str_to_replace1 = array("年","月");
    $str_to_replace2 = "日";
    $new_date_part1 = str_replace($str_to_replace1, "-", $new_date[0]);
    $new_date_part1 = str_replace($str_to_replace2, "", $new_date_part1);

    $new_date_part2 = explode(":", $new_date[1]);
    $hour = "";
    $min = $new_date_part2[1];
    $sec = $new_date_part2[2];
    if (stripos($new_date_part2[0], "下午") !== false) {
        $temp = str_replace("下午", "", $new_date_part2[0]);
        $hour = $temp+12;
    } else {
        $temp = str_replace("上午", "", $new_date_part2[0]);
        $hour = $new_date_part2[0];
    }

    return $new_date_part1.' '.$hour.':'.$min.':'.$sec;
}

change:

public function getElementHtml()
{
    $this->addClass('input-text');

    $html = sprintf(
        '<input name="%s" id="%s" value="%s" %s style="width:110px !important;" />'
        .' <img src="%s" alt="" class="v-middle" id="%s_trig" title="%s" style="%s" />',
        $this->getName(), $this->getHtmlId(), $this->getRawMysqlDateFormat($this->_value), $this->serialize($this->getHtmlAttributes()),
        $this->getImage(), $this->getHtmlId(), 'Select Date', ($this->getDisabled() ? 'display:none;' : '')
    );
    $outputFormat = $this->getFormat();
    if (empty($outputFormat)) {
        throw new Exception('Output format is not specified. Please, specify "format" key in constructor, or set it using setFormat().');
    }
    $displayFormat = Varien_Date::convertZendToStrFtime($outputFormat, true, (bool)$this->getTime());
    $test = $this->getRawMysqlDateFormat($this->_value);
    $html .= sprintf('
        <script type="text/javascript">
        //<![CDATA[
            Calendar.setup({
                inputField: "%s",
                ifFormat: "%s",
                showsTime: "true",
                button: "%s_trig",
                align: "Bl",
                singleClick : true
            });
        //]]>
        </script>',
        $this->getHtmlId(), "%Y-%m-%d %H:%M:%S",
        $this->getTime() ? 'true' : 'false', $this->getHtmlId()
    );

    $html .= $this->getAfterElementHtml();

    return $html;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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