Friday, April 22, 2011

Fixing Time Mismatch in PHP, mySQL and Server on CentOS

Recently, I was informed by my development & networks team that there's a timing mismatch on one of our dedicated servers which is affecting cron execution and that they are unable to fix it. Most of our servers don't have Webmin, Kloxo or any other WHM, and we manage them via Putty/Commandline or FTP.

This one had Kloxo/HyperVM installed and even the Time Zone function in the Kloxo wasn't fixing the time offset. Server was showing the correct local time, mySQL was 7 hours behind whereas the PHP was one hour ahead. The fix for all entities wasn't listed at a single source so I had to search from various sources to fix it. 

I normally don't blog about technology but I thought I should publish the fix so if anyone of you ever comes across a similar issue, may be it helps him/her too.

Setting Server Time

Stop ntpd if running
# /etc/init.d/ntpd stop
sync time with ntp server
# /usr/sbin/ntpdate
27 Aug 01:10:56 ntpdate[27008]: adjust time server offset -0.048726 sec
Keep the original zone file
# cp /usr/share/zoneinfo/Asia/City/usr/share/zoneinfo/Asia/City_orig_YYYYmmDD
Make a new zone file
# cat /tmp/Karachi
Rule Country Min Max – Jun 19 04:20:59 1 PKT
Rule Country Min Max – Oct  28 23:59:59 0 PKT
Zone Asia/City+5:00 Country%s
compile the new zone file
# zic /tmp/City
See the time has changed
# date
Thu Mar 28 02:05:34 PKT 2011
See if ntp daemon is still running
# ps -ef | grep ntp
root 1982 1188 0 Aug18 ? 00:00:05 /usr/sbin/ntpmon
root 1996 1 0 Aug18 ? 00:00:02 /usr/sbin/ntpd -g
root 31246 30980 0 02:06 pts/0 00:00:00 grep ntp


first, make a backup of the existing localtime file. It’s always good practice to make backups of original config files.
# mv /etc/localtime /etc/localtime.bak
Next, create the link:

# ln -s /usr/share/zoneinfo/Asia/Karachi /etc/localtime
Run # date to confirm the correct time.

PHP Time Fix

For checking the php time, put the following code in a file, say test.php

    $time = time();
    $result = date(”Y-m-d (D) H:i:s”,$time);
    echo “Current date and local time on  server = $result   “;
Execute the php script.

[root@localhost ~]# php -a time.php
    Interactive mode enabled
    Current date and local time on  server = 2011-04-21 (Thu) 18:04:25
To get the server time , issue the following command :

[root@localhost ~]# date
    Thu Apr 21 17:04:25 PKT 2011
You can see the difference of one hour between the server time and the php time.
For fixing this, you need to install the PECL timezonedb module.

[root@localhost ~]# pecl install timezonedb
At the end , you might see the following message :

Build process completed successfully
Installing ‘/usr/local/lib/php/extensions/no-debug-non-zts-20060613/timezonedb.s o’
install ok: channel://
configuration option “php_ini” is not set to php.ini location
You should add “” to php.ini

So , add the line ”” to the php.ini file and restart apache using command /etc/init.d/httpd restart

There shouldn’t be any mismatch in time now. Use the test.php page again to confirm

mySQL Time Fix

Execute the following command on commandline.

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

username root didn't allow modification due to security reasons so I used another DB Username. You'll be prompted for DB User Password as well.


So this is how I synchronized all clocks on my server. If you want me to write more about similar stuff or the technology challenges we come across daily, do let me know by posting your comments.