The problem
Storing datetimes can be a issue if servers and users of your application are distributed around the World and use different time zones. Each user want to work on datetimes in his specific time zone, servers automatically stores values in their time zone, etc. Storing data without operating right conversion will cause strange behaviours.
The solution
The solution is very simple: store all datetimes in UTC time zone and show to each user in his proper time zone. This is, gnerally, a well documented technique, but the following code will explain how to realize this operation in Doctrine 2 and Zend Framework 2 environment. To do this, we will assume you just have a working ZF2 project with a configured DoctrineORMModule (refer to official documentation to reach this achievement).
First of all, lets create a custom Doctrine Datatype to handle DateTime object in UTC. Field of this type will automatically convert value into UTC time zone before store it in DB. The following code is a modification of official doctrine Working with DateTime instances article that at this moment (2013-03-12) has an error in usage of DateTime format() method. Please, note that you can put this file where you prefer inside /module/Application/src/Application/.
/module/Application/src/Application/DBAL/Types/UTCDateTimeType.php:
|
|
To make this Datatype work in a Zend Framework 2 project, we need to load it in our DoctrineORMModule configuration. So let’s edit ZF2 module configuration file by adding the following code:
/module/Application/config/module.config.php:
|
|
At this point we can use Datatype UTCDateTime to map DateTime property of our entities like in the following example. Please note that the location of entities depends on your DoctrineORMModule configuration.
/module/Application/src/Application/Entity/Event.php:
|
|
Now, when we use $event->setDatetime() method, the value will be stored in DB in UTC time zone. For this reason, we need to re-convert it into user time zone before show.
After retrieved an object that contains a DateTime property, let’s set timezone before show with code like:
|
|
Please note that time zone and format strings can be retrieved from user preference or automatically detected.
Conclusion
At this point we can simply work with DateTime in Doctrine 2 + Zend Framework2 environment.
Please, keep in mind that this is only an example and can be heavly improved.
See also
- How to setup Docker container with legacy PHP 5.6 and Xdebug
- Split, reduce and convert PDF to JPEG using PHP ImageMagick
- Quickly setup HTTPS on PHP Apache2 Docker container with self-signed SSL certificate
- Building ZF3 composed pages using Nesting View Models and Forward Controller Plugin
- How to inject Zend Service Manager in ZF3 Controllers