I added this line to my config.inc.php file.
$query = "SET SESSION time_zone = 'Europe/Rome'";
if (mysql_query($query, DB_LINK) == FALSE) {
die(mysql_error(DB_LINK));
}
It doesn't give me any error, but when I use the NOW() or the CURRENT_TIMESTAMP() function it saves the record with a wrong time.
How can I set the date time zone in MySQL without the super permissions?
Assuming you are using 5.5, if you see http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html, it says:
mysql> SET time_zone = timezone;
It also says:
The current session time zone setting affects display and storage of time values that are zone-sensitive. This includes the values displayed by functions such as NOW() or CURTIME(), and values stored in and retrieved from TIMESTAMP columns. Values for TIMESTAMP columns are converted from the current time zone to UTC for storage, and from UTC to the current time zone for retrieval.
The current time zone setting does not affect values displayed by functions such as UTC_TIMESTAMP() or values in DATE, TIME, or DATETIME columns. Nor are values in those data types stored in UTC; the time zone applies for them only when converting from TIMESTAMP values. If you want locale-specific arithmetic for DATE, TIME, or DATETIME values, convert them to UTC, perform the arithmetic, and then convert back.
So try it without the SESSION and see if it works, and also check that select ##session.time_zone;
gives you the right timezone.
EDIT: you may just have an issue with your database. I just tried this on one of my databases (5.5.8) and it worked, but it failed on 5.0.51. So you may need a db upgrade.
mysql> select CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2011-05-29 14:33:06 |
+---------------------+
1 row in set (0.00 sec)
mysql> set time_zone = 'Europe/Rome';
Query OK, 0 rows affected (0.00 sec)
mysql> select CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2011-05-29 16:33:11 |
+---------------------+
1 row in set (0.00 sec)
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.5.8-log |
+-----------+
1 row in set (0.00 sec)
Erm I'm not sure how to set time zone with mysql...
but i prefer to set the time zone with php...
date_default_timezone_set('Europe/Rome');
Related
I want to convert this format of datetime "31-12-2018 19:30 hs." from Argentina to an UTC timestamp, I am using the following code:
$clean_date = substr($date, 0, -4);
$dt = new DateTime($clean_date, new DateTimeZone('America/Argentina/Buenos_Aires'));
$dt->setTimeZone(new DateTimeZone('UTC'));
$timestamp = $dt->getTimestamp();
But it doesn't work, in the database the record is "0000-00-00 00:00:00", but if I echo the $dt, till there is working perfectly and showing the datetime in UTC.
Could someone please help me?
Thanks.
This has nothing to do with PHP. You're simply using the incorrect date literal format in MySQL. A per the docs:
MySQL recognizes DATETIME and TIMESTAMP values in these formats:
As a string in either 'YYYY-MM-DD HH:MM:SS' or 'YY-MM-DD HH:MM:SS' format. A “relaxed” syntax is permitted here, too: Any
punctuation character may be used as the delimiter between date parts
or time parts.
As a string with no delimiters in either 'YYYYMMDDHHMMSS' or 'YYMMDDHHMMSS' format, provided that the string makes sense as a
date.
As a number in either YYYYMMDDHHMMSS or YYMMDDHHMMSS format, provided that the number makes sense as a date.
1546335960 could be the last case but numbers don't make sense as date because year 1546 did not have 33 months.
To make it worse, many MySQL Servers are configured by default to let these kind of errors slip through:
mysql> CREATE TABLE test (
-> foo TIMESTAMP
-> );
Query OK, 0 rows affected (0.74 sec)
mysql> SET ##SESSION.sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO test (foo) VALUES (1546335960);
Query OK, 1 row affected, 1 warning (0.39 sec)
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'foo' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM test;
+---------------------+
| foo |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)
As you can see, you got a mere warning (that you need to read explicitly) and data corruption.
If you configure your app to use a strict mode you'll get a proper error message just in time:
mysql> SET ##SESSION.sql_mode = 'TRADITIONAL,NO_AUTO_VALUE_ON_ZERO';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO test (foo) VALUES (1546335960);
ERROR 1292 (22007): Incorrect datetime value: '1546335960' for column 'foo' at row 1
mysql>
Please note that timestamp is just a generic English word:
A digital record of the time of occurrence of a particular event.
It isn't necessarily synonym for Unix time.
I have a problem, I'm using mysql with PHP and I have in my database timestamp columns that are automatically set on update by the current timestamp. But when I'm trying to insert rows into the table the rows are added with timestamp different from my current time (before two hours) I have the EST timezone.
I've checked the timezone for the database and it is System and when I searched for that I read that it depeneds on the machine that is connecting, but my machine has EST time, so can anyone explain why I'm having this? and what can I do to set the current timestamp for my database to EST?
I've personally found it to be a lot more reliable to set the timezone in PHP, then grab the timestamp there and pass this to your MySQL query.
Something like:
date_default_timezone_set('America/New_York');
$curtimestamp = date('Y-m-d G:i:s', time());
Then use the value of $curtimestamp in your queries.
The documentation may have been unclear.
time_zone=SYSTEM means that the MySQL Server time zone is derived from the host that the MySQL Server is running on, not the client system.
So, if the time zone on the MySQL server host is different from the time zone of the client host, that explains the behavior that you observe.
Each client (database session) has its own time_zone setting. When the connection is established, the setting is derived from the "default" time zone for the MySQL server.
The setting of this variable determines how DATETIME and TIMESTAMP values are interpreted, when values are sent to the database from the client, AND when existing values are pulled from the database.
A client can issue a SET time_zone statement to change the time_zone for the database session, e.g.
SET time_zone=CST6CDT
(Note that to use named values for time zones, the time_zone% tables in the mysql database must be populated.)
To set the "default" time_zone that will be used for new database connections, you can set the "global" time_zone variable:
SET GLOBAL time_zone=
(This change requires SUPER privilege, and it impacts ALL new database connections to the entire instance. Normally, this value is set in the MySQL server configuration file.)
For TIMESTAMP columns, MySQL stores those as UTC. The values returned to the client depend on the setting of the client time_zone. As a simple demonstration:
mysql> CREATE TABLE mytest
-> ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
-> , ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
-> );
Query OK, 0 rows affected (0.11 sec)
mysql> SHOW VARIABLES LIKE 'time_zone';
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| time_zone | +00:00 |
+---------------+--------+
1 row in set (0.00 sec)
mysql> INSERT INTO mytest (id) VALUES (NULL);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM mytest;
+----+---------------------+
| id | ts |
+----+---------------------+
| 1 | 2015-01-09 15:41:25 |
+----+---------------------+
1 row in set (0.00 sec)
mysql> SET time_zone = 'CST6CDT';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM mytest;
+----+---------------------+
| id | ts |
+----+---------------------+
| 1 | 2015-01-09 09:41:25 |
+----+---------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO mytest (id) VALUES (NULL);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM mytest;
+----+---------------------+
| id | ts |
+----+---------------------+
| 1 | 2015-01-09 09:41:25 |
| 2 | 2015-01-09 09:41:25 |
+----+---------------------+
2 rows in set (0.00 sec)
mysql> SET time_zone = 'EST5EDT';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM mytest;
+----+---------------------+
| id | ts |
+----+---------------------+
| 1 | 2015-01-09 10:41:25 |
| 2 | 2015-01-09 10:41:25 |
+----+---------------------+
2 rows in set (0.00 sec)
How can I get an update another field (whole column) the difference of time in (TIME 00:00:00) format in my MYSQL phpMyAdmin database
<?php
$con=mysqli_connect("***","****","****","******");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
mysqli_query($con,"UPDATE members SET time_on = current_time-logon_time");
?>
I keep getting 0:00:00 and no results when I do this in PHP. The other times our fine, just trying to get the difference and update all fields in the time_on column.
You should use timediff()
mysqli_query($con,"UPDATE members SET time_on = timediff(current_time,logon_time)");
You can use TIMESTAMPDIFF() to get the difference between two dates and/or datetimes.
Try this:
UPDATE members
SET time_on = TIMESTAMPDIFF(SECOND, logon_time, current_time)
This will set the difference in seconds.
Just to expand on why the other answers are right: You're doing MATH on times, which doesn't work as you expect:
mysql> create table foo (x time, y time);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into foo (x, y) values ('14:15:16', '09:08:07');
Query OK, 1 row affected (0.00 sec)
mysql> select * from foo;
+----------+----------+
| x | y |
+----------+----------+
| 14:15:16 | 09:08:07 |
+----------+----------+
1 row in set (0.00 sec)
mysql> select x - y from foo;
+-------+
| x - y |
+-------+
| 50709 |
+-------+
1 row in set (0.00 sec)
Note how the result is NOT a time value, it's an integer. It happens to be a direct time->string->numeric conversion of 05:07:09, which is the literal as-expected time difference of the two values. But since you're doing MATH, i.e. subtraction, MySQL is assuming you want a numeric answer, and giving it to you.
That's why there's timediff() and similar date/time functions, which return a real date/datetime value, not this wonky/useless integer.
I'm starting to design a database and before too many records get inputted, I want to think into the future and collect as much data as possible. I think it would be good for me to know when the record was added. Based on your experience, is it better to do this through mySQL via datetime or through php via the date function. I'll be using php to input all the values, so it would simply be another field.
So far, I like the php approach because I can customize it to take up minimal space: yymmddhhmm & time zone.
Based on your experience, what is the best way to store this data or are the two ways indifferent?
Also, what time zone would you suggest using? The time zone where I am located or GMT? Is it best to use GMT if say I were to move later on or if individuals from multiple timezones administered the database.
Store it as DATETIME/TIMESTAMP in MySQL, it is stored as an integer anyway, just goes in and comes out as a timestamp. Store the data in UTC.
You can manipulate the timestamp in PHP by constructing it with DateTime() and then going from there.
This also allows you to put a NOT NULL DEFAULT CURRENT_TIMESTAMP on the column, which saves you actively having to build it in php.
For simplicity, I suggest using MySQL's timestamp field. Because the database then understands what it is, it's stored much more efficiently than your text version (as a number, rather than a string of characters), and you can do more with it.
For example:
mysql> CREATE TABLE foo (something TEXT NOT NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO foo (something) VALUES ("one");
Query OK, 1 row affected (0.07 sec)
mysql> INSERT INTO foo (something) VALUES ("two");
Query OK, 1 row affected (0.13 sec)
mysql> SELECT * FROM foo;
+-----------+---------------------+
| something | created |
+-----------+---------------------+
| one | 2013-09-18 22:57:01 |
| two | 2013-09-18 22:57:03 |
+-----------+---------------------+
2 rows in set (0.00 sec)
mysql> SELECT something, NOW() - created as seconds_since_insert FROM foo;
+-----------+----------------------+
| something | seconds_since_insert |
+-----------+----------------------+
| one | 136 |
| two | 134 |
+-----------+----------------------+
2 rows in set (0.00 sec)
I want to use the NOW() function with a specific timezone, say GMT+8 for a user and GMT-2 for another user. How can I achieve this?
I am guessing that the time for NOW() is related somewhat to the timezone and time of the SQL server, but I want it to be such that FN(GMT+8) always give me the NOW() in GMT+8 irregardless of the timezone the SQL server is in.
Mini question: How do i display/know the current time of the SQL server?
The NOW() function provides the current time in the local timezone of the server. If you wish to convert to a different timezone, you can use CONVERT_TZ()
UPDATE:
You can use a per-connection timezone (that doesn't affect the system timezone) and get the effect you want:
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2011-06-03 22:40:51 |
+---------------------+
1 row in set (0.00 sec)
mysql> SET time_zone = '+08:00';
Query OK, 0 rows affected (0.00 sec)
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2011-06-04 10:41:15 |
+---------------------+
1 row in set (0.00 sec)