Wrong time zone in mysql - php

Working with php and mysql.
In test.php file have this simple script:
echo date('Y m d h:i');
echo date_default_timezone_get();
DB::execute('insert into test (date) values (now()) ');
In the browser it displays GMT as a result of server date_default_timezone_get function and date like "2015 07 16 20:06". However in the DB the value is stored with 2 hours added to the date like it was in central europe time (2015 07 16 22:06).
I've checked the mysql variable TIME_ZONE is set to SYSTEM, so I think that the date stored in the DB should be the same as it is displayed from php server? I'm in central europe in the moment, is it possible that mysql knows this somehow and sets the date based on my computer system timezone?
when I run this i mysql
select ##time_zone, now(), utc_timestamp()
i receive:
SYSTEM | 2015-07-16 22:27:22 | 2015-07-16 20:27:22
Also I've see that other mysql variable SYSTEM_TIME_ZONE is set to CEST. maybe that's why i have date stored in central europe timezone? Even if in php i have different time zone and mysql TIME_ZONE is set to system?
Date field in the table is datetime format

Related

Get result from query in timezone user rather than timezone DB

I have a Mysql DB on time zone UTC and PHP server in Timezone Europe, Bucharest (GMT+03:00).
When query like giving me result in month=8 and year=2018, because different Timezone there's some result in month 7. The result in month 8 in DB Timezone start from 31-07-2018 21:00 to 31-08-2018 21:00 not (start from 01-08-2018 00:00 to 31-08-2018 23:59) is a real result for my client in his time zone.
So is there a way to set Timezone on query and get exactly result meet Timezone of my client?

Difference in date value in localhost

In my localhost WAMP stack, I am having a database table which has a column "Birth-date" as a "date-time" column type.
I am running the below SQL for that table to get the birth-date of the current year and its unix timestamp value. No issues here.
SELECT dateValue,
DATE_ADD(dateValue, INTERVAL YEAR(CURDATE())-YEAR(dateValue) YEAR) "Date1",
UNIX_TIMESTAMP(
DATE_ADD(dateValue, INTERVAL YEAR(CURDATE())-YEAR(dateValue) YEAR)
) "Date2"
FROM base_date
For example I get the below output from the SQL.
DATEVALUE DATE1 DATE2
-------------------------------+-------------------------------+-----------------
December, 18 1980 00:00:00+0000 December, 18 2013 00:00:00+0000 1387305000
December, 20 1985 00:00:00+0000 December, 20 2013 00:00:00+0000 1387477800
The problem is that when I try to display that unix formatted timestamp value in PHP, the date is not shown correct. There is a change of 1 day.
echo gmdate("Y-m-d", "1387305000"); // Displays 2013-12-17 and not 2013-12-18
echo gmdate("Y-m-d", "1387477800"); // Displays 2013-12-19 and not 2013-12-20
The confusing part is that :
When I test this with SQL Fiddle values, it worked correct. The unix timestamp out of the SQL is different for the same date in my localhost mysql(5.5.24) and the version available in sqlfiddle.com(5.5.32).
Fiddle: http://sqlfiddle.com/#!2/25e032/3/0
What could be the difference? Is it related to timezone or sql version or something else?
My host has the timezone set on MySQL to their local timezone (Pacific Time), so a PHP time() value (GMT) put into the database and displayed as a MySQL time is off by 8 hours or so. So, it may be a matter of your host's MySQL configuration. Be careful about mixing PHP timestamps and MySQL timestamps.
You are using gmdate() which adjusts to GM timezone. What is the default timezone set for your PHP? Try changing gmdate() to date() and see if it works correctly.
date_default_timezone_get() -> http://www.php.net/manual/en/function.date-default-timezone-get.php
On the gmdate() documentation you can get an explanation, look at Example 1:
http://www.php.net/manual/en/function.gmdate.php

MySql UNIX_TIMESTAMP() stored as UTC with Daylight Savings approaching

My DB server (running MySql 5.5) is set to UTC, and dates are stored as Unix timestamps in the database using UNSIGNED INT. The database is primarily used for storing tasks which are run at a specific time (exec_time).
I insert tasks by creating a timestamp in PHP using the timezone of the user logged in (BST in this instance). For example, I have a task set to run at 1351396800 which is for tomorrow morning at 4am GMT.
I pluck tasks out of the database with the following query:
SELECT * FROM tasks WHERE exec_time <= UNIX_TIMESTAMP();
When the clocks roll back one hour tomorrow at 2am will this setup be ok?
Update: PHP is converting the dates fine. With PHP timezone set to Europe/Dublin (Currently BST) Two events added for 12 midnight and then 4am are stored as follows:
mysql> select exec_time, FROM_UNIXTIME(exec_time) from tasks order by id desc limit 2;
+-------------+----------------------------+
| exec_time | FROM_UNIXTIME(exec_time) |
+-------------+----------------------------+
| 1351378800 | 2012-10-27 23:00:00 |
| 1351396800 | 2012-10-28 04:00:00 |
tl;dr You should be fine as long as your exec_time column has a TIMESTAMP data type.
There isn't an explicit UNIX_TIMESTAMP column datatype. There is a TIMESTAMP column data type. Values for columns of this data type are converted automatically from your client connection's time zone to UTC (a/k/a Z or Zulu time, f/k/a Greenwich Mean Time) when being converted from a date/time string and from UTC to your client connection's time zone upon conversion to a date/time string.
So, if you're storing your exec_time column as a TIMESTAMP, you should be able to use the clause you propose:
WHERE exec_time <= UNIX_TIMESTAMP()
This will work because both your exec_time values and the result of the UNIX_TIMESTAMP() function call are handled in UTC on the server side. Your exec_time values will be stored in UTC.
If you're storing exec_time as an UNSIGNED INT or a similar numeric data type, you won't have been able to take advantage of the automatic conversion to UTC before storing.
You can mess with the display conversion behavior by setting your client connection time_zone as follows:
SET time_zone='SYSTEM' /* for your system's local time */
or
SET time_zone='+0:00' /* for UTC */
or
SET time_zone'America/New_York' /* or 'Europe/Vienna' or whatever */
Once you've issued one of these SET operations, do
SELECT exec_time, FROM_UNIXTIME(exec_time)
to get a sense of how your values are stored server side and translated.
If you want to see what will happen eight days on, try this:
SELECT 3600*24*8+exec_time, FROM_UNIXTIME(3600*24*8+exec_time)
http://dev.mysql.com/doc/refman/5.5/en//time-zone-support.html
In answer to your question, it depends how critical the time fields are, and whether the server's local time will change or not. If it's UTC then it probably won't change.
The temporal types in MySQL aren't timezone aware. You'll have to implement timezones yourself, perhaps by always storing a UTC timestamp/datetime and a separate timezone column which contains an interval offset from +12 to -12 hours for how much time to add or subtract to the UTC timestamp for the timezone.
The actual handling of what value to put in the timezone field and the work needed to retrieve a timestamp adjusted for the timezone are up to you, unfortunately.
If switching to Postgres is an option then you can always use the TIMESTAMP WITH TIMEZONE type that Postgres supplies.

Mysql Current Timestamp and time() showing different values

OK. So I have been trying to implement a timer. Now a very weird thing is happening and I can't understand why ?.
Basically I am trying to find the difference between the last access and the current time. I am storing the time of last access in the database. This value is according to the server time. But when I try the time() function of php it shows me values which are 5-6 hours behind the time that I have in the database.
For example: here is my code :
$t1= strtotime($played_row->timer); // Time from the database with CURRENT_TIMESTAMP
$t2= strtotime("now"); // Get the current time
It shows Year: 2012 Month: 01 Day: 21 - 05:28 pm for t2
and Year: 2012 Month: 01 Day: 21 - 10:28 pm for my timestamp values.
Can anyone tell my why is that ?
P.S: I am running the code on my computer itself.
At a guess I would say that your database and PHP are using two different timezone offsets.
Most likely this is a timezone issue: if you are in the Eastern timezone, you are 5 hours away from UTC right now. If one sytem is returning local time and another is returning UTC this is what you will see.
Try using date_default_timezone_set() to set the timezone in PHP that is used in your database.
date_default_timezone_set — Sets the default timezone used by all
date/time functions in a script
Alse see date_default_timezone_get() how to get ini-set timezone.

Timezone differences between PHP and MySQL

I've run in to an issue whereby PHP and MySQL seem to disagree on which timezone they should be using when converting certain timestamps back to date and time.
The problem arises when I have a timestamp which I would like to convert back to a datetime format. PHP gives the date and time based on GMT being the timezone, but MySQL seems to think it is operating in GMT+1, and converts accordingly.
Simple reproduction
$original_date = '2009-08-31 23:59:59';
$timestamp = strtotime($original_date);
echo $timestamp; // Gives 1251763199
echo date('Y-m-d H:i:s', $timestamp); // PHP: 2009-08-31 23:59:59
echo db_field('SELECT FROM_UNIXTIME(1251763199)'); // MySQL: 2009-09-01 00:59:59
The timestamp given by PHP seems to be the correct one for the date given, assuming timezone is GMT. The result from MySQL would have been the correct one had we been running BST (timestamp given fell within GMT+1 at that time).
If I try the above with a $timestamp from today (1267640942), PHP and MySQL both seem to be happy to tell me that it is 2010-03-03 18:29:02 (both returning GMT).
What timezone is set on the servers?
I've checked the MySQL docs, which say that if my timezone is set to system than the OS will provide the timezone info. This appears to be the case at the moment:
mysql> SELECT ##global.time_zone, ##session.time_zone;
+--------------------+---------------------+
| ##global.time_zone | ##session.time_zone |
+--------------------+---------------------+
| SYSTEM | SYSTEM |
+--------------------+---------------------+
The default timezone on my web server is GMT. This is also the default system timezone on my database server (according to the date command run on the cl on each server).
foo#bar:/home/foo$ date
Wed Mar 3 18:45:02 GMT 2010
So according to the docs, my DB server should be running on GMT, which is what we want. Yet the query output given in my test scripts suggests that it's running in GMT+1.
I know there are a number of workarounds for this problem (all date arithmetic being done fully in either PHP or MySQL, etc) but I'd love to get to the bottom of what's causing this discrepancy so we can sort it out and prevent anyone else on the team from being tripped up by it.
Does anyone know if there's a very basic setting that I've over-looked here, or know what could be causing this discrepancy?
Thanks!
i use this methodology:
take care of PHP and leave mysql alone
it is recommended to set default timezone for php via date_default_timezone_set php function.
use a TIMESTAMP field type for keeping date record in mySql
then when you insert:
$sDate = date("Y-m-d H:i:s");
mysql_query("insert into `table` set `created_on` = '$sDate' ");
and when you select:
mysql_query("select `created_on` from `table` ");
$iTime = strtotime($aRow['created_on']);
you can always have access to global time using gmdate php function:
$iTime_Global = gmdate("U", $iTime);
the mysql timezone would have no effect in your application if you just take care of your PHP code. (that is made by timezone set)
I would suggest using UTC on your server and MySQL install and convert the timezone(s) to what ever you want. The conversion in MySQL and PHP are fairly simple.
http://www.w3schools.com/php/php_ref_date.asp (getTimezone and setTimezone)
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html

Categories