I have a cronjob which runs every hour. This cronjob should write to database when dataset was updated. My SQL Query in php looks like this
INSERT INTO allstats (site_id, adformat_id, imps, clicks, conv, net_pub_comp, created_at, updated_at) VALUES (?,?,?,?,?,?,"'.date("Y-m-d H:i:s").'", "'.date("Y-m-d H:i:s").'")
I print out date("Y-m-d H:i:s") and i get 2013-06-28 04:05:17
that is fully right date and time. after that i make a select now() in mysql and time is also the same. timezone on server is set to Europe/Berlin. That timezone is also set in php and mysql. everywhere i get the right time.
But why on insert the datetime column have a value which is 2 hours before the real time? I hope someone have an idea. Thanks for you help.
If the datetime that you're inserting is the datetime of script execution why not just use NOW() in your insert statement?
INSERT INTO allstats (site_id, adformat_id, imps, clicks, conv, net_pub_comp, created_at, updated_at)
VALUES (?,?,?,?,?,?,NOW(),NOW())
Less parameters to bind and pass.
MySQL date/times should be stored in the UTC time zone. Your application should calculate the difference and convert that date/time into the appropriate time zone.
Related
I am living in Sri Lanka. I have this code to record the current date and time when invalid login done.
$insert_query = "INSERT INTO LoginAttempt(IpAddress, LoginAt) VALUES('". $_SERVER['REMOTE_ADDR']. "', CURRENT_TIMESTAMP)";
I have uploaded to hostinger.co.uk which is free webhosting service for educational purpose.
That inserted into table successfully. It shows the date correct. But time is about 5 hours and 30 minutes less than the actual time.
Is there any way to change timezone in cPanel or programmatically in the PHP script?
What I have tried;
1) addes this. but does not work! date_default_timezone_set('Asia/Colombo');
Another soulution to use DATE_ADD function to add the particular missing hours.
What are your another ideas? Thanks
MySQL table;
CREATE TABLE LoginAttempt(
LoginId INT NOT NULL AUTO_INCREMENT,
IpAddress VARCHAR(20) NOT NULL,
LoginAt DATETIME NOT NULL DEFAULT NOW(),
PRIMARY KEY(LoginId)
);
Solution that worked!!!!
$insert_query = "INSERT INTO LoginAttempt(IpAddress, LoginAt) VALUES('". $_SERVER['REMOTE_ADDR']. "', CONVERT_TZ(NOW(), 'UTC', 'Asia/Colombo') )";
This server in England is probably running on UTC time. Sri Lanka, is, not coincidentally, 5:30 ahead of UTC. Your server is certainly recording the correct time in your table. It's just in the wrong zone.
These people operating the shared server aren't going to change that just for you: you share the server with people from all around the globe. (Note that it's considered good practice to operate servers on UTC time everywhere, so you would have the same problem if your server were down the hall.)
Change your LoginAt column's data type from DATETIME to TIMESTAMP. TIMESTAMP values are always recorded in UTC and always translated to local time when displayed.
Then, whenever you connect to MySQL (from a program or in PhpMyAdmin) issue the
SET time_zone = 'Asia/Colombo'
command you have already discovered, before you do anything else. Then you'll see your TIMESTAMP data displayed in local time.
Alternatively, if you have existing DATETIME or DATE time data you know is recorded respect to UTC, you can convert it in MySQL using CONVERT_TZ(). For example,
SELECT CONVERT_TZ(LoginAt, 'UTC', 'Asia/Colombo') LoginAt, ...
will give you your information in local time.
The thing to know is that TIMESTAMP data types, NOW(), CURDATE(), CURRENT_TIMESTAMP and so forth are retrieved using the time zone setting. DATETIME and DATE are not. So, your program gets the CURRENT_TIMESTAMP implicitly transforming it to UTC local time, and stores it into your DATETIME column, congealing the time to UTC.
If your program stored it into a TIMESTAMP column the time zone of the stored time would not be congealed. Alternatively, if your program issued the set time_zone = 'Asia/Colombo' command before issuing the query in your question, it would congeal the time into your local time before storing it into your DATETIME column.
Confusing? Yes.
I have a PHP MySQL query that inserts some data into a MySQL database and it includes a timestamp.
Currently the INSERT query uses NOW() for the the timestamp column and it is saved in the database in the following format: 2012-07-24 13:13:02
Unfortunately for me the Server is not in my time zone and it is listed as America/Los_Angeles as shown print date_default_timezone_get();
I was hoping to do the following:
date_default_timezone_set('Europe/London');
$timefordbLondonEU = date('Y-m-d H:i:s', time());
and simply save into the database the $timefordbLondonEU in place of the NOW();
Is this a good way to save such data ?
Many Thanks,
Richard
[ADDED TEXT]
I changed the Type in the MySQL db to DateTime and did the following:
date_default_timezone_set('Europe/London');
$timefordbLondonEU = date('Y-m-d H:i:s', time());
It is working but Im still not getting the overall concept yet.
Assumptions based on your comments:
MySQL = Does not have a datatype UTC you simply use type INT.
Unix_TimeStamp() will save the current time or count? in UTC format such as 1343247227.
As UTC is a count from a common 0 point you can get any timezone from it. Assuming that you don't want a date before the reference 0 point in 1970.
My guess and lead on from what you have said is the best way to do it is save the time as UTC in an INT (1343247227) and then generate any time zones you want from there. Again assuming you don't need to store dates before the reference 0 point in 1970.
Equally why not store as datetime YYYY-MM-DD HH:MM:SS at a known timezone and then convert to UTC or other timezones. It all seems pretty messy =(
As #Petah said in the comments, store your times in UTC and covert them in the application as needed.
Unix timestamps are in UTC so I usually store my times in the database as timestamps. This saves the headache and confusion of first converting to UTC to insert, and then from UTC when selecting.
That is, make your time field an INT type, and use the function UNIX_TIMESTAMP() in MySQL when you insert, or get the timestamp from PHP using the time() function.
When you fetch the timestamp from the DB it will be in UTC, but when you display it in your PHP application using date(), it will display in the server timezone, or whatever you set with date_default_timezone_set.
Therefore the following two queries will work:
INSERT INTO `table` (id, time) VALUES(NULL, UNIX_TIMESTAMP());
// or
$time = time();
$query = "INSERT INTO `table` (id, time) VALUES(NULL, $time);
If you want to select it from the DB as a DATETIME, you can do this:
SELECT *, FROM_UNIXTIME(time) as dt FROM `table` WHERE 1
The resulting dt column will be in the format yyyy-MM-dd hh:mm:ss.
You can format the numeric timestamp in PHP using date()
If the PHP version you have is 64-bit, you aren't limited to the 1970 - 2036 range, PHP will support 64-bit timestamps, just make sure to use a BIGINT column in MySQL in that case.
Hope that helps.
I don't know what kind of value I should store in the database.
I'm thinking I should do something like this, but I don't know how:
Store the years, days, hours, minutes since a give date like 1/1/2000
Then at another time I will compare that value against the current years, days, hours, and minutes since 1/1/2000. Obviously, the difference between the two would be the time since the user's last login.
I appreciate any help anyone can provide on this.
Thanks in advance
Why not just use a TIMESTAMP or a DATETIME? That's literally all you need.
mysql will do this for you. It will store the number of seconds since 1 Jan 1970. And calculate the difference.
Try this: SELECT NOW();. You will see now's date/time. Try SELECT UNIX_TIMESTAMP(NOW()); and you'll see the number of seconds since Epoch (but you don't need that usually).
You should store this value everytime the user logs in, which means insert now() into a table or update a last_login field.
You have two options:
INSERT INTO user_login_history (user_id, login_date) VALUES (1, NOW());
and
UPDATE users SET last_login=NOW() WHERE user_id=1;
Note that the last_login and login_date fields will have to be of either DATETIME type (to store date and time) or TIMESTAMP or DATE (only date) or TIME (only time).
Also, you can do time calculations in mysql with DATEDIFF, like so:
SELECT NOW(), DATEDIFF(NOW(), DATE('2012-6-5'));
In your table, SELECT DATEDIFF(NOW(), last_login) AS "days_since_last_login" FROM users;
You can store the timestamp of the last login and then just do the arithmetic. Maybe you should look at the DateTime::diff method to let PHP do the hard maths ;-)
This will be done with PHP.
I basically want to get the number of rows that were inserted 30 minutes ago.
I have a time field on my table which is type TIMESTAMP and on update it's set to CURRENT_TIMESTAMP.
The date is stored in this format:
2011-05-27 04:29:17
My query is supposed to look something like this, however i just can't do it
SELECT COUNT(*) FROM mytable WHERE UNIX_TIMESTAMP(time) < '.time().'-1800
Where time() is PHP's function that fetches the UNIX time.
What it should basically do is print me the number of rows inserted from now to 30 minutes ago, but i just can't seem to make it work.
Can somebody help?
Small edit:
Another problem i am seeing is that php's function time() displays the unix time which is UTC. The time stored in mysql is probably GMT i.e whatever my computer's time/timezone is set to.
You can easily get rows stored from now to 30 mins ago by simply using:
SELECT count(*) FROM mytable WHERE `time` >= DATE_SUB(UTC_TIMESTAMP, INTERVAL 30 minute)
Usage of UTC_TIMESTAMP is just an example if you're storing your date/time data as UTC_TIMESTAMP(), you can probably use NOW() if necessary, depends on what you're storing really.
**EDIT**
Removed bad pointers and fixed example :)
Do you really need your computer's timezone to be different than UTC? why not just set it to UTC & save yourself the confusion? If that doesn't work, just use dateadd() on mysql to convert your mysql timestamp to UTC when checking?
My suggestion would be to write a small function to convert the mysql timestamp to your PHP timestamp format & load it into mysql. Then all you need to do is to call tmstamp(time_stamp) instead of time_stamp in your query. You can do the reverse too i.e. Convert PHP's "30 minutes ago" timestamp to mysql format and rerun your query (probably easier).
Usually it's just a formatting issue. It's not standardized across programs.
I use
date_default_timezone_set($_SESSION['time_zone']);
to set a users timezone on a page, I am wanting to know, how do I save current time to mysql in php with the current UTC date and time? Also should I be storing it as a timestamp?
My existing site used datetime fields and when I saved a new item to mysql I could just use now() in the php part making the insert or update query
Here are the relevant MySQL functions if you'd rather do it in your SQL:
SELECT UTC_TIMESTAMP(), UTC_DATE(), UTC_TIME();
UTC_TIMESTAMP() is what you're looking for if you want to store as a DATETIME field
gmdate('U'); outputs the GMT/UTC timestamp of the specified timestamp based on the current timezone.
See more information on the PHP Manual page