I'm trying to insert a date time value e.g. 1970-01-01 00:00:01 in a column of timestamp datatype in MySQL table but getting following error:
#1292 - Incorrect datetime value: '1970-01-01 00:00:01' for column 'order_date' at row 1
But according to MySQL docs - The TIMESTAMP value has a range from '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
So if the range value starts from 1970-01-01 00:00:01 UTC then why this value can't be inserted in the table? Is there something to do with UTC? What will be the minimum date time value for timestamp that can be inserted without any issue?
Timestamp columns store a utc value and start at 1970-01-01 00:00:01, but whenever you read or write them, they convert to/from your session timezone. This makes them something of a nightmare to work with if you are actually intending to only use UTC.
Just use a datetime type if you ever are trying to set particular times that come from your client. If you must use timestamp and want to set a particular UTC time, first do:
set session time_zone='+00:00';
But note that any client that doesn't do that may see a different time. Even if you set your server timezone to UTC, so that sessions default to UTC, some client libraries "helpfully" set the session timezone when they connect.
UPDATE test SET add_time = '2017-04-29' WHERE id = 1;
The type of 'add_time' is timestmap,the above statement will be inserted '2017-04-29 15:00:00',my question is why it is not '2017-04-29 00:00:00'.It may be related to the time zone of mysql?
In MySQL 5 and above, TIMESTAMP values are converted from the current time zone to UTC for storage, and converted back from UTC to the current time zone for retrieval. (This occurs only for the TIMESTAMP data type, and not for other types such as DATETIME.)
By default, the current time zone for each connection is the server's time. The time zone can be set on a per-connection basis, as described in MySQL Server Time Zone Support.
2017-04-29 15:00:00 means that its a time of 3 PM, 29th April, 2017. Timestamp saves date and time as well. And that time is because of the time zone.
However if you need to select datepart only, you can do the following:
SELECT date(ColumnName) from tablename
The above will get only the date part only.
The DATETIME type is used when you need values that contain both date
and time information. MySQL retrieves and displays DATETIME values in
'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01
00:00:00' to '9999-12-31 23:59:59'.
...
The TIMESTAMP data type has a range of '1970-01-01 00:00:01' UTC to
'2038-01-09 03:14:07' UTC. It has varying properties, depending on the
MySQL version and the SQL mode the server is running in.
For your situation, I will suggest you to use datetime instead of timestamp
I try to insert this date "2014-06-18T12:32:56.575+10:00" in timestamp field. But is saved "2014-06-18 12:32:56" without timezone. How can I convert date to UTC or other timezone?
Use datetime datatype instead of timestamp.
As per MySQL documentation:
MySQL converts TIMESTAMP values from the current time zone to UTC for
storage, and back from UTC to the current time zone for retrieval.
This does not occur for other types such as DATETIME
If your are already using datetime then set default timezone of MySQL or set timezone per connection.
I need to store both time and date in the mysql. So I used of NOW() function for that. But I don't know what should I use for type column im phpmyadmin. It should be noted that NOW() returns both time and date like this:
2014-11-11 12:45:34
Here is a solution, I can use of a separator for separating date and time (2014-11-11 and 12:45:34) and then store them in the DATE type and TIME type individually. Or I can use of VARCHAR type for storing both of them in one column. But I think these ways are not standard. what is standard type for storing both date and time ?
Here is my query: (also I don't know why NOW() function does not works)
INSERT INTO table (timedate) VALUES (NOW())
DATE: It is used for values with a date part but no time part. MySQL retrieves and displays DATE values in YYYY-MM-DD format. The supported range is 1000-01-01 to 9999-12-31.
DATETIME: It is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in YYYY-MM-DD HH:MM:SS format. The supported range is 1000-01-01 00:00:00 to 9999-12-31 23:59:59.
TIMESTAMP: It is also used for values that contain both date and time parts, and includes the time zone. TIMESTAMP has a range of 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC.
TIME: Its values are in HH:MM:SS format (or HHH:MM:SS format for large hours values). TIME values may range from -838:59:59 to 838:59:59. The hours part may be so large because the TIME type can be used not only to represent a time of day (which must be less than 24 hours), but also elapsed time or a time interval between two events (which may be much greater than 24 hours, or even negative).
I have a slightly different perspective on the difference between a DATETIME and a TIMESTAMP. A DATETIME stores a literal value of a date and time with no reference to any particular timezone. So, I can set a DATETIME column to a value such as '2019-01-16 12:15:00' to indicate precisely when my last birthday occurred. Was this Eastern Standard Time? Pacific Standard Time? Who knows? Where the current session time zone of the server comes into play occurs when you set a DATETIME column to some value such as NOW(). The value stored will be the current date and time using the current session time zone in effect. But once a DATETIME column has been set, it will display the same regardless of what the current session time zone is.
A TIMESTAMP column on the other hand takes the '2019-01-16 12:15:00' value you are setting into it and interprets it in the current session time zone to compute an internal representation relative to 1/1/1970 00:00:00 UTC. When the column is displayed, it will be converted back for display based on whatever the current session time zone is. It's a useful fiction to think of a TIMESTAMP as taking the value you are setting and converting it from the current session time zone to UTC for storing and then converting it back to the current session time zone for displaying.
If my server is in San Francisco but I am running an event in New York that starts on 9/1/1029 at 20:00, I would use a TIMESTAMP column for holding the start time, set the session time zone to 'America/New York' and set the start time to '2009-09-01 20:00:00'. If I want to know whether the event has occurred or not, regardless of the current session time zone setting I can compare the start time with NOW(). Of course, for displaying in a meaningful way to a perspective customer, I would need to set the correct session time zone. If I did not need to do time comparisons, then I would probably be better off just using a DATETIME column, which will display correctly (with an implied EST time zone) regardless of what the current session time zone is.
TIMESTAMP LIMITATION
The TIMESTAMP type has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC and so it may not usable for your particular application. In that case you will have to use a DATETIME type. You will, of course, always have to be concerned that the current session time zone is set properly whenever you are using this type with date functions such as NOW().
Saty described the differences between them. For your practice, you can use datetime in order to keep the output of NOW().
For example:
CREATE TABLE Orders
(
OrderId int NOT NULL,
ProductName varchar(50) NOT NULL,
OrderDate datetime NOT NULL DEFAULT NOW(),
PRIMARY KEY (OrderId)
)
You can read more at w3schools.
In shorter explanation
DATE: The DATE stores a date value in the form YYYY-MM-DD (year-month-day). It does not store time.
TIME: The TIME stores a time value in the form HH:MM:SS (hours-minutes-seconds). It does not store the date.
DATETIME: The DATETIME stores a date and time value in the form YYYY-MM-DD HH:MM:SS. It stores both the date and time.
TIMESTAMP: The TIMESTAMP is similar to the DATETIME, but includes a timezone. (Example of values YYYY-MM-DD HH:MM:SS +HH:MM, YYYY-MM-DD HH:MM:SS -HH:MM. +HH:MM and -HH:MM indicate the time zone from UTC (Coordinated Universal Time).
Follow up question of
https://serverfault.com/questions/191331/should-servers-have-their-timezone-set-to-gmt-utc
Should the MySQL timezone be set to UTC or should it be set to be the same timezone as the server or PHP is set? (If it is not UTC)
What are the pros and cons?
It seems that it does not matter what timezone is on the server as long as you have the time set right for the current timezone, know the timezone of the datetime columns that you store, and are aware of the issues with daylight savings time.
On the other hand if you have control of the timezones of the servers you work with then you can have everything set to UTC internally and never worry about timezones and DST, at least when it comes to storing internal time.
Here are some notes I collected of how to work with timezones as a form of cheatsheet for myself and others which might influence what timezone the person will choose for his/her server and how he/she will store date and time.
MySQL Timezone Cheatsheet
Notes:
Changing the timezone will not change the stored datetime or
timestamp, but it will select a different datetime from
timestamp columns
Warning! UTC has leap seconds, these look like '2012-06-30 23:59:60' and can
be added randomly, with 6 months prior notice, due to the slowing of
the earths rotation
GMT confuses seconds, which is why UTC was invented.
Warning! different regional timezones might produce the same datetime value due
to daylight savings time
The timestamp column only supports dates 1970-01-01 00:00:01 to 2038-01-19 03:14:07 UTC, due to a limitation.
Internally a MySQL timestamp column is stored as UTC but
when selecting a date MySQL will automatically convert it to the
current session timezone.
When storing a date in a timestamp, MySQL will assume that the date
is in the current session timezone and convert it to UTC for
storage.
MySQL can store partial dates in datetime columns, these look like
"2013-00-00 04:00:00"
MySQL stores "0000-00-00 00:00:00" if you set a datetime column as
NULL, unless you specifically set the column to allow null when you
create it.
Read this
To select a timestamp column in UTC format
no matter what timezone the current MySQL session is in:
SELECT
CONVERT_TZ(`timestamp_field`, ##session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
You can also set the sever or global or current session timezone to UTC and then select the timestamp like so:
SELECT `timestamp_field` FROM `table_name`
To select the current datetime in UTC:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), ##session.time_zone, '+00:00');
Example result: 2015-03-24 17:02:41
To select the current datetime in the session timezone
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
To select the timezone that was set when the server launched
SELECT ##system_time_zone;
Returns "MSK" or "+04:00" for Moscow time for example, there is (or was) a MySQL bug where if set to a numerical offset it would not adjust the Daylight savings time
To get the current timezone
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
It will return 02:00:00 if your timezone is +2:00.
To get the current UNIX timestamp (in seconds):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
To get the timestamp column as a UNIX timestamp
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
To get a UTC datetime column as a UNIX timestamp
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', ##session.time_zone)) FROM `table_name`
Get a current timezone datetime from a positive UNIX timestamp integer
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
Get a UTC datetime from a UNIX timestamp
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), ##session.time_zone, '+00:00')
FROM `table_name`
Get a current timezone datetime from a negative UNIX timestamp integer
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
There are 3 places where the timezone might be set in MySQL:
Note: A timezone can be set in 2 formats:
an offset from UTC: '+00:00', '+10:00' or '-6:00'
as a named time zone: 'Europe/Helsinki', 'US/Eastern', or 'MET'
Named time zones can be used only if the time zone information tables
in the mysql database have been created and populated.
in the file "my.cnf"
default_time_zone='+00:00'
or
timezone='UTC'
##global.time_zone variable
To see what value they are set to
SELECT ##global.time_zone;
To set a value for it use either one:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET ##global.time_zone='+00:00';
##session.time_zone variable
SELECT ##session.time_zone;
To set it use either one:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET ##session.time_zone = "+00:00";
both "##global.time_zone variable" and "##session.time_zone variable" might return "SYSTEM" which means that they use the timezone set in "my.cnf".
For timezone names to work (even for default-time-zone) you must setup your timezone information tables need to be populated: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html
Note: you can not do this as it will return NULL:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Setup mysql timezone tables
For CONVERT_TZ to work, you need the timezone tables to be populated
SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;
If they are empty, then fill them up by running this command
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
if this command gives you the error "data too long for column 'abbreviation' at row 1", then it might be caused by a NULL character being appended at the end of the timezone abbreviation
the fix being to run this
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql
echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql
mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql
(make sure your servers dst rules are up to date zdump -v Europe/Moscow | grep 2011 https://chrisjean.com/updating-daylight-saving-time-on-linux/)
See the full DST (Daylight Saving Time) transition history for every timezone
SELECT
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND) AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC
CONVERT_TZ also applies any necessary DST changes based on the rules in the above tables and the date that you use.
Note:
According to the docs, the value you set for time_zone does not change, if you set it as "+01:00" for example, then the time_zone will be set as an offset from UTC, which does not follow DST, so it will stay the same all year round.
Only the named timezones will change time during daylight savings time.
Abbreviations like CET will always be a winter time and CEST will be summer time while +01:00 will always be UTC time + 1 hour and both won't change with DST.
The system timezone will be the timezone of the host machine where mysql is installed (unless mysql fails to determine it)
You can read more about working with DST here
When not to use UTC by the legendary Jon Skeet: https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/
(For example a scheduled event in the future that represents a time, not an instant in time)
related questions:
How do I set the time zone of MySQL?
MySql - SELECT TimeStamp Column in UTC format
How to get Unix timestamp in MySQL from UTC time?
Converting Server MySQL TimeStamp To UTC
https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
How do I get the current time zone of MySQL?
MySQL datetime fields and daylight savings time -- how do I reference the "extra" hour?
Converting negative values from FROM_UNIXTIME
Sources:
https://bugs.mysql.com/bug.php?id=68861
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html
http://dev.mysql.com/doc/refman/5.1/en/datetime.html
http://en.wikipedia.org/wiki/Coordinated_Universal_Time
http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
https://web.ivy.net/~carton/rant/MySQL-timezones.txt
PHP and MySQL have their own default timezone configurations. You should synchronize time between your data base and web application, otherwise you could run some issues.
Read this tutorial: How To Synchronize Your PHP and MySQL Timezones
This is a working example:
jdbc:mysql://localhost:3306/database?useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Europe/Moscow
The pros and cons are pretty much identical.It depends on whether you want this or not.
Be careful, if MySQL timezone differs from your system time (for instance PHP), comparing the time or printing to the user will involve some tinkering.
How about making your app agnostic of the server's timezone?
Owing to any of these possible scenarios:
You might not have control over the web/database server's timezone settings
You might mess up and set the settings incorrectly
There are so many settings as described in the other answers, and so many things to keep track of, that you might miss something
An update on the server, or a software reset, or another admin, might unknowing reset the servers' timezone to the default - thus breaking your application
All of the above scenarios give rise to breaking of your application's time calculations. Thus it appears that the better approach is to make your application work independent of the server's timezone.
The idea is simply to always create dates in UTC before storing them into the database, and always re-create them from the stored values in UTC as well. This way, the time calculations won't ever be incorrect, because they're always in UTC. This can be achieved by explicity stating the DateTimeZone parameter when creating a PHP DateTime object.
On the other hand, the client side functionality can be configured to convert all dates/times received from the server to the client's timezone. Libraries like moment.js make this super easy to do.
For example, when storing a date in the database, instead of using the NOW() function of MySQL, create the timestamp string in UTC as follows:
// Storing dates
$date = new DateTime('now', new DateTimeZone('UTC'));
$sql = 'insert into table_name (date_column) values ("' . $date . '")';
// Retreiving dates
$sql = 'select date_column from table_name where condition';
$dateInUTC = new DateTime($date_string_from_db, new DateTimeZone('UTC'));
You can set the default timezone in PHP for all dates created, thus eliminating the need to initialize the DateTimeZone class every time you want to create a date.
Check Timezone
SELECT ##system_time_zone as System_tz ,##global.time_zone as MYSQL_timeZone, NOW() as timenow_bymysql;
SET GLOBAL time_zone = '+05:30';
OR
change system time zone then restart MariaDB/MYSQL
and check again timezone