Magento – Customer created_at Date off by months

ce-1.8.1.0datemagento-1.8

I'm working on syncing my customers with a third party application and have discovered that many of my created_at dates are way off.

Today is 2014-04-08 yet I have several records with a created_at date in the future – 2014-06-01, 2014-06-03, 2014-05-06

I'm not exactly sure where to start troubleshooting.

This question touches on the issue, but it (and it's duplicate) are both more related to the multiple updates. I'm not seeing the created_at date changing on save/update, but I am having the date be off by days or months.

I poked around the /app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Time/Created.php and /app/code/core/Mage/Core/Model/Locale.php files but didn't see anything obviously wrong.

Does anyone have any advice about how to have accurate created_at dates? Should I comment out code similar to @alex's solution?

I'm using Magento 1.8.1.0

Timezone is CST – America/Chicago

Locale: English (United States)

Best Answer

The problem is in Mage_Eav_Model_Entity_Attribute_Backend_Time_Created::beforeSave. This line ends up swapping the month and day:

$zendDate = Mage::app()->getLocale()->utcDate(null, $date, true, $this->_getFormat($date));

This happens to just about all entity types including products and customers, and happens during creation and normal save events, in both CE >= 1.8.x and EE >= 1.13.x.

Override this model in your own module, and replace the beforeSave method with this:

public function beforeSave($object)
{
    $attributeCode = $this->getAttribute()->getAttributeCode();
    $date = $object->getData($attributeCode);
    if (is_null($date)) {
        if ($object->isObjectNew()) {
            $object->setData($attributeCode, Varien_Date::now());
        }
    } else {
        // ADD THIS
        $date = strtotime($date);

        // convert to UTC
        $zendDate = Mage::app()->getLocale()->utcDate(null, $date, true, $this->_getFormat($date));
        $object->setData($attributeCode, $zendDate->getIso());
    }

    return $this;
}

This also needs to be corrected on the way out of the database. Replace afterLoad with this:

public function afterLoad($object)
{
    $attributeCode = $this->getAttribute()->getAttributeCode();
    $date = $object->getData($attributeCode);

    // ADD THIS
    if (!is_null($date)) {
        $date = strtotime($date);
    }

    $zendDate = Mage::app()->getLocale()->storeDate(null, $date, true, $this->_getFormat($date));
    $object->setData($attributeCode, $zendDate->getIso());

    parent::afterLoad($object);

    return $this;
}

Edit: Here is an example of how to override this class.

<global>
    <models>
        <eav>
            <rewrite>
                <entity_attribute_backend_time_created>Mycompany_Mymodule_Model_Eav_Entity_Attribute_Backend_Time_Created</entity_attribute_backend_time_created>
            </rewrite>
        </eav>
    </models>
</global>

Then create the file app\code\local\Mycompany\Mymodule\Model\Eav\Entity\Attribute\Backend\Time\Created.php