Magento Timezones and Timestamps

Posted by Joaquín Ruiz on 29th April 2016

Magento Timezones and Timestamps

Understanding Magento Timezones is essential and very useful. Did you know that all of the dates in your Magento are stored using UTC? If you run a Magento store in countries that use Daylight Saving Time, like UK, Spain, Germany… [link] you should know that your store times may be wrong for half of the year as the time-zone switches between GMT to BST or DST.

Magento timezones behaviour

Magento sets script’s time relative to server time, converted to UTC/GMT. This is because we cannot always know in what timezone the server will be hosted (cloud servers?), and we can have different websites on different timezones. This way we can deliver a consistent system timezone for our customers.

You can set different timezones for each store. To set a time-zone for your Store, go to:

Admin panel > System > Configuration > General > Locale Options > Timezone
Magento Timezones
Magento Timezones

Then, each Magento store (database-wise) is synced to UTC/GMT. Therefore Summer-time countries will have one hour ahead of GMT during summer.

In conclusion, you could have some problems with the UTC-equivalent standard Time.

Problems

Catalogue Rules

Magento resets price-rules back for an insane reason everyday, even if the discount remain in effect for 5 months. In order to apply these rules everyday, Magento uses a cron job. If the cron job timezone is misconfigured, the catalogue price rules will disappear after midnight, and the Magento crons can mail you errors like ‘too late for schedule’.

Note: If you struggle to get the cron working properly, I recommend to use the module [Aoe Scheduler]

Magento displays products on frontend and checks if there are catalogue rules for this date. This date is the local store date. However, when catalogue rules are being applied, it uses GMT date.


app/code/core/Mage/CatalogRule/Model/Action/Index/Refresh.php

$timestamp = $coreDate->gmtTimestamp('Today');

The ‘catalogrule_apply_all’ cron job is executed at 01am. Therefore, if you are in DST timezone, the catalogrule_apply_all will execute one hour before (UTC-2), in this case 23pm, so it will stop your catalogue rules from working at midnight.

In my humble opinion, I think Magento core developers should have use the Store timestamp instead:

$timestamp = Mage::app()->getLocale()->date(null, null, null, true)->get(Zend_Date::TIMESTAMP);

Date-times attributes

If you need to update the date-time attributes of an entity in Magento, you should use GMT dates, Magento will translate them to automatically.

Therefore, you have to be careful when working with order, product, invoices, etc. timestamps:

* To retrieve the creation time of an invoice we could use two methods:

$invoice->getCreatedAt(); // Returns UTC 
$invoice->getCreatedAtStoreDate(); // Returns local timezone 

* To set created_at date use this method:

Mage::getSingleton('core/date')->gmtDate();

* To get a created_at date in your store timezone you can use this code:

$created_at = Mage::helper('core')->formatDate($order->getCreatedAt(), 'medium', true);

Working with timestamps

Magento sets script’s time relative to server time, converted to UTC. To retrieve the current timestamp, we have to differentiate between server time and Magento time.

For the server:

$currentTimestamp = time(); 

For Magento:

$currentTimestamp = Mage::getModel('core/date')->timestamp(time()); // Gets the timezone and converts it

This also applies to templates, if you are using a date picker on your frontend, when you save updated or created dates, always use GMT time.

Mage::getModel('core/date')->gmtDate()

 

Conclusions

  • Keep in mind that Magento stores the dates in UTC.
  • Make sure you have your Store timezone correctly set.
  • As UTC does not change to Summer time, be careful with the cron jobs that interact with internal server times (like the catalogue price rules).

 




About the author:

Joaquín Ruiz is a Computer Engineer, Senior PHP Developer and Magento Certified Developer. Joki has more than 7 years of experience working with multiple PHP frameworks. He knows Magento, WordPress, Laravel, Yii.. like the back of his hand ;)


  • marco

    Top post, you made my day. I was comparing 2 dates with `time()` instead of `Mage::getModel(‘core/date’)->timestamp()` in a template.

    • Thanks, that is a common mistake when working with multiple Store-Timezones, or when your server timezone is different than the Magento one.