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