I’ll guide you through Magento’s timezone behavior, as I’ve noticed that people tend to get confused in cases when they have 2 or more websites with different timezones. If this is what you are searching for, read on!
First of all, let’s start with the Web server – Magento relation, and their times.
Web server – Magento relation
Let’s look at the following scenario. You want an online store – ok, you’ll need a web hosting for it (on some web hosting providers server). With classic low-level PHP development people tend to overlook server’s settings, and each server has it’s own time and timezone set. If you overlook that, each time your script executes any of time functions, it will take server time as actual one. So first thing you need to look at, is server location, and its time zone.
In case of Magento, the situation is a bit different. Let’s take a look at index.php (first executed PHP file on server):
Mage::run($mageRunCode, $mageRunType);
And that line starts Magento initialization.
Now, let’s move forward, to app/Mage.php file. In there, you’ll find this:
self::$_app->run(array(
'scope_code' => $code,
'scope_type' => $type,
'options' => $options,
));
After we trace it a bit more, we’ll come across this method:
//File: "app/code/core/Mage/Core/Model/App.php"
/**
* Initialize PHP environment
*
* @return Mage_Core_Model_App
*/
protected function _initEnvironment()
{
$this->setErrorHandler(self::DEFAULT_ERROR_HANDLER);
//Sets the default timezone used by all date/time functions in a script
//Mage_Core_Model_Locale::DEFAULT_TIMEZONE = 'UTC' by default
date_default_timezone_set(Mage_Core_Model_Locale::DEFAULT_TIMEZONE);
return $this;
}
Oh look, Magento sets script’s time relative to server time, converted to UTC. So each Magento store (database-wise) is synced to UTC.
Someone might ask why should we do this, and why wouldn’t we just set it to timezone that suits our needs. Well, it’s a good question – but the answer is better:
If you have your Magento installation on cloud for example, or even on come cluster, it will help with cross-server synchronization as “UTC stands for Coordinated Universal Time” and pretty much each configuration of each server considers that as a default, if not set otherwise.
Now, this explains how Magento gets / calculates timezone.
Moving on to
Magento Per Store Timezone Settings
If you navigate to “System->Configuration->General->Locale Options->Timezone” in Admin area of Magento, you’ll see that you can change Timezone for each Website you have. This way you get a way to have stores for each part of the world set with correct timezone.
Here’s a method used to fetch current time per store (Zend_Date instance):
//File: "app/code/core/Mage/Core/Model/Locale.php"
/**
* Create Zend_Date object with date converted to store timezone and store Locale
*
* @param mixed $store Information about store
* @param string|integer|Zend_Date|array|null $date date in UTC
* @param boolean $includeTime flag for including time to date
* @return Zend_Date
*/
public function storeDate($store=null, $date=null, $includeTime=false)
{
$timezone = Mage::app()->getStore($store)->getConfig(self::XML_PATH_DEFAULT_TIMEZONE);
$date = new Zend_Date($date, null, $this->getLocale());
$date->setTimezone($timezone);
if (!$includeTime) {
$date->setHour(0)
->setMinute(0)
->setSecond(0);
}
return $date;
}
Or if you need string representation, just use this:
/**
* Date and time format codes
*/
/*
const FORMAT_TYPE_FULL = 'full';
const FORMAT_TYPE_LONG = 'long';
const FORMAT_TYPE_MEDIUM= 'medium';
const FORMAT_TYPE_SHORT = 'short';
*/
Mage::helper('core')->formatTime($time=null, $format='short', $showDate=false);
//Or "$this->helper('core')->formatTime($time=null, $format='short', $showDate=false);"
Front-end and Back-end views
On back-end you’ll always see times shown as configured on “System->Configuration->General->Locale Options->Timezone” for “Default” scope (usually set to Admin’s timezone). Example where you can see tis is on order views page.
And each time shown on front-end will be shown as configured on same place, but on website scope. Although there aren’t may places on front-end where exact time is shown, it’s important for dates (if you have limited time offers for example), or for Cron tasks set for specific stores (newsletter sending etc.).
Conclusion
As I’ve mentioned at the very beginning of this article. This all applies to single-store setup as well, but it is of a HUGE importance if you have multi-store setup. If it’s set incorrectly it might lead to some “ghost bugs”, and it’s quite hard to trace – especially if you (developer) don’t understand how exactly it works.
I hope I’ve cleared few things here. And thanks for reading!
P.S.
If you notice some strange behavior of time related stuff, please submit it here to comments!