Our production platform technologies are these: PHP, MS SQL Sever, and IIS.
PHP is set to the timezone 'Pacific/Auckland' which is current +12:00 GMT/UTC.
When we retrieve dates from SQL Server, they are consistently 12 hours 'behind' what they should be, ie. SQL Server is storing and serving them as GMT dates, even though the time zone on the server itself is Pacific/Auckland too.
Is there a hidden sp function some where you can use to set the timezone? If this is not timezone related, please enlighten me!
Can you open up sql server management studio and type "select getdate()" to make sure it is sql server that is wrong?
Are you using getdate() or another sql function to get the date?
If your statement is both accurate and general, then you should be able to reproduce this simply by inserting a row into a table with a datetime column like this:
CREATE TABLE OffBy12 (
IsThisOff datetime not null
)
GO
INSERT INTO OffBy12 (IsThisOff) VALUES ('2009-06-28')
SELECT IsThisOff
FROM OffBy12
If you're right, then the time portion of the date will not be 00:00.
If you're not correct, then this must be something more complex. In that case, you may want to say how the data are getting into SQL Server.
Related
I am working on a project based on PHP i have an issue that i purchased a hosting whose server is of another country and i am in Pakistan when i enter data in database table from PHPMyAdmin in enters the date of that country which is 11 hours behind us that's why my insert queries and update queries not working Php time zone is set but server time zone is not set.
php_value date.timezone 'Asia/Karachi';
i use this is my htaccess file Also use
date.timezone = "Asia/Karachi"
in php ini file
(To long for comment)
If you write a website with user specific timezones, then managing timezones at database site is a bit complicated. I prefer this solution:
Try to store all timestamp as bigint values in unix time.
Converting time to string only at user interface.
Examples
For Database storing I use:
UPDATE table SET start_time = UNIX_TIMESTAMP();
Results are either retrieved as native integers or converted to UTC/GMT time:
SELECT unix_time, UNIX_TIMESTAMP(db_date)
You can test it with:
SELECT UNIX_TIMESTAMP(), UNIX_TIMESTAMP(now());
In PHP, you can now simply do fast time calculations by adding and substracting. It printing a time at the user interface, set the timezone (maybe evaluated by a database query) and use date() or strftime(), or any date+time class.
You should set your MySQL timezone when you open the connexion to the database server in PHP.
You can see some example here: Set timezone in PHP and MySQL
You could also do it like this (works with MariaDB, never tested on MySQL):
$db->exec("SET time_zone='Asia/Karachi';");
That way you don't have to update your database configuration and you can update the set depending on a variable.
I have a script which has to do a "Google Analytics" like task.
Basically display visitor statistics for a user.
I want to generate a report in the time zone of the user who is requesting it.
So far I have written a code with this:
SET time_zone = timezone;
What it does it sets the time zone per each MySQL connection. If a user retrieves data with timestamp the timestamp is converted to the timezone of the connection. I am storing the UTC in the timestamp.
So everything seems to work. But some people are saying that this is a wrong approach. Because multiple user can't connect to the database with different time_zone setting.
But the MySQL doc says:
Per-connection time zones. Each client that connects has its own time
zone setting, given by the session time_zone variable. Initially, the
session variable takes its value from the global time_zone variable,
but the client can change its own time zone with this statement
However they keep insisting that you should not do anything with time zone in MySQL at all. You should do it all in your (for example) PHP code.
Here a similar question with this answer.
But how can I do it in the PHP code? I mean I know how to convert a time with a time zone in PHP but it's not like I am retrieving a single row.
I am retrieving thousands of rows and GROUP them by the date in the timestamp field:
SELECT ...
FROM logs
WHERE
user_id = :user_id
AND timestamp >= CURDATE()
GROUP BY DATE(timestamp)
It is very important that MySQL is using the index of timestamp because I have millions of. Does the index work even though I am using a function on the timestamp GROUP BY DATE(timestamp)? If not how else could I accomplish this?
So how should I do this all? I would be really thankful for some advice.
Now User converts all timestamps to his tz and uses timestamp(*user) >= CURDATE(*user).
I think the other way is to
convert timestamp(user) to timestamp(server)
and use
timestamp(*server) >= CURDATE(*server)
example
dates =(5,6,7)
(convert to my tz) dates-2 = (3,4,5)
(check constrain directly with this array )biggerThan3 result=(4,5)
2nd way
(convert constraint to ts server) biggerThan3 -> biggerThan(3+2)5
(check constraint with server array) dates =(5,6,7) result=(6,7)
result can be converted to (4,5)
In my PHP.ini file I set the TimeZone like so...
'America/New_York'
so when i ran a simple php Date() function
echo date("Y-m-d H:i:s");
I get the Correct dateTime according to 'MY' system time as that's what i am comparing against and want to store in my MySQL db as well. (as reported from PHP).
Now the problem is, i exported a MySQL db to PDF format, just to see what it looked like, and the time was 1 hour back, ex.. it was (10:00 a.m.) here and the PDF footer said (9:00 a.m.)
So.. i got to thinking.. my PHP script will INSERT into the db the correct dateTime that i need.. But i have alot of dateTime comparing going on for accounts,
I know if i run any MySQL Queries in phpMyAdmin then i will get the wrong dateTime.
i have tried running in (phpMyAdmin SQL Query)
SET time_zone = 'America/New_York';
-and-
SET time_zone = '-05:00';
But when I run the query
SELECT ##global.time_zone, ##session.time_zone;
I get back SYSTEM and SYSTEM.
(I should also mention i am on shared hosting)
If I use the MySQL NOW() function in my query, the time entered into the db will be calculated by MySQL, according to it's own timezone.
like this..
mysql_query("INSERT INTO table (id, value, time_created)
VALUES ('{$id}', '{$value}', NOW())");
I understand that I will have to do all of my INSERTING and comparing in PHP to keep the times right.. but with the above, it will insert the wrong time.
so this is my dilemma...
But will this affect anything that i am not foreseeing? I just feel like somehow this will affect my times.
So how can I get around this or get MySQL on the SAME timezone? and make sure that ALL my date/times are right, not the 1 hour behind..
Two queries ran successively through PhpMyAdmin will be executed in two separate sessions (connections) therefore SELECT ##session.time_zone alone will always return "SYSTEM".
I doubt you can (and I hope you cannot) change the global time zone on a shared server, so always expect "SYSTEM" for SELECT ##global.time_zone. On the other hand you should be able to change your session's time zone.
Try running these two queries in one execution, it should show the new time zone :
SET time_zone = '-05:00'; SELECT ##session.time_zone; -- same session
NOW() returns time in the current session time zone, so time zone does matter. However I would rather store times in GMT time zone, but I suppose that's more a matter of taste.
Depending on what you may do and what you may not do (on your shared hosting) you could choose to either use the following statement as the start of all your queries: "set time_zone='-05:00';", for example: "set time_zone='-05:00'; select foo from bar;" or (maybe the most reliable option): only use timestamps in your tables and queries and create DateTime objects in PHP based on the timestamp you received.
I have this table
Name Birth_Date Register_Date
---------------------------------------------------------------
Ali 1990-03-22 2010-03-1 15:1:42
Ali1 1991-07-18 2010-03-2 12:44:2
When I inserted these values, I inserted the Birth_Date as a String such as '1990-03-22', and I used 'NOW()' for Register_Date.
NOW() will generate the current datetime according to the MySql Server.
Now when I try to get the time between the current date and the Register_Date (Time passed since he registered), I use the following:
SELECT YEAR(CURDATE())-YEAR(register_date) ...
In PHP, if I wanted to do that, I suppose I have to get the current date: date('Y-m-d H:i:s');
My question is, is there a difference between calculating the date difference (between a date and today) via MySql or via PHP?
Currently, on my localhost (XAMPP), CURDATE() and date(..) generates the same date, but will it generate the same date for other users when my website goes online?
If both your mysql and PHP server are operating on the same timezone and have their clocks properly synchronized, you wont have an issue.
if you want to upload your php website and your DB on the same server I think you'll not have problem , but If you use different servers you may have time issues.
to avoid this issue I advice you to save the time with time zone, to be able to get the correct time from any server.
I have two Windows 2008 servers with IIS, PHP and MSSQL.
In a PHP-script, I query a table with a field of type 'datetime':
SELECT timestamp FROM table
Now the problem is, that on one server I get this format:
2012-02-05 12:32:54.020
But on the other server I get this (which I donĀ“t want):
Feb 5 2012 12:32PM
When querying through SQL Server Management Studio I get the 'correct' (2012-02-05 12:32:54.020) value on both servers.
My question is:
How do I disable this conversion in PHP so that the format returned is always in this format: 2012-02-05 12:32:54.020?
Edit: I know that I could change the script to format the date, but I don't want to go through 10000+ files. What is causing this conversion? Is it PHP, SQL or IIS? It is working on the old server, so I assume it could work on the new server.
In PHP, you can format the date with date_format like this:
$correctDate = date_format($dateToFormat, "Y-m-d H:i:s");
You may format it on server side:
SELECT CONVERT(varchar, timestamp, 121) FROM table