There is a manual page on Time and Date functions.
The best way to compare date and time and get minutes back is probably to use one of the following:
SELECT TIME_TO_SEC(TIMEDIFF(timea,timeb)+0)/60
SELECT TIMESTAMPDIFF(MINUTE,timeb,timea)
Note that while TIMEDIFF
works with times, TIMESTAMPDIFF
requires a date component - and the values are switched around for TIMESTAMPDIFF
.
You can return hours with either of these:
SELECT TIME_TO_SEC(TIMEDIFF(timea,timeb)+0)/60/60
SELECT TIMESTAMPDIFF(HOUR,timeb,timea)
Note that when using DATEDIFF
, the value returned is a difference between the date components of the given time - thus, a value of 23:59 on one day compared to a value of 0:01 on the next (a 2 minute difference) results in a date difference of 1 (a full day).
To get a difference between two times in 24-hour periods (length of a day) first calculate the difference in minutes then divide by the proper values to find the number of 24-hour periods. Try this:
SELECT TRUNCATE(TIMESTAMPDIFF(MINUTE,timeb,timea)/60.0/24.0,0)
This truncates the decimal portion, returning only the number of complete 24-hour periods in the specified timespan.
MySQL is behaving correctly – your test is invalid.
If you round-trip through a time zone with DST, you will not have a lossless conversion if you hit a transition. The timestamp in question occurs during a DST transition in "CET" and "Europe/Berlin".
There are two wall clock times in Asia/Bangkok that correspond to a single wall clock time in Europe/Berlin.
mysql> SELECT CONVERT_TZ('2013-10-27 08:15:33','Asia/Bangkok','Europe/Berlin');
+------------------------------------------------------------------+
| CONVERT_TZ('2013-10-27 08:15:33','Asia/Bangkok','Europe/Berlin') |
+------------------------------------------------------------------+
| 2013-10-27 02:15:33 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CONVERT_TZ('2013-10-27 07:15:33','Asia/Bangkok','Europe/Berlin');
+------------------------------------------------------------------+
| CONVERT_TZ('2013-10-27 07:15:33','Asia/Bangkok','Europe/Berlin') |
+------------------------------------------------------------------+
| 2013-10-27 02:15:33 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)
Check this with a conversion to UTC...
mysql> select convert_tz('2013-10-27 02:59:59','Europe/Berlin','UTC');
+---------------------------------------------------------+
| convert_tz('2013-10-27 02:59:59','Europe/Berlin','UTC') |
+---------------------------------------------------------+
| 2013-10-27 00:59:59 |
+---------------------------------------------------------+
1 row in set (0.00 sec)
Two seconds later...
mysql> select convert_tz('2013-10-27 03:01:01','Europe/Berlin','UTC');
+---------------------------------------------------------+
| convert_tz('2013-10-27 03:01:01','Europe/Berlin','UTC') |
+---------------------------------------------------------+
| 2013-10-27 02:01:01 |
+---------------------------------------------------------+
1 row in set (0.00 sec)
...it is one hour and two seconds later.
Or, flip it around.
mysql> SET @@time_zone = 'CET';
mysql> SELECT FROM_UNIXTIME(1382825733) AS zero,
FROM_UNIXTIME(1382825733 + 3600) AS one,
FROM_UNIXTIME(1382825733 + 3600 + 3600) as two,
FROM_UNIXTIME(1382825733 + 3600 + 3600 + 3600) as three,
FROM_UNIXTIME(1382825733 + 3600 + 3600 + 3600 + 3600) as four;
+---------------------+---------------------+---------------------+---------------------+---------------------+
| zero | one | two | three | four |
+---------------------+---------------------+---------------------+---------------------+---------------------+
| 2013-10-27 00:15:33 | 2013-10-27 01:15:33 | 2013-10-27 02:15:33 | 2013-10-27 02:15:33 | 2013-10-27 03:15:33 |
+---------------------+---------------------+---------------------+---------------------+---------------------+
^^ ... wait, what? .. ^^
1 row in set (0.00 sec)
If you do a timezone conversion on an ambiguous value during the transition hour, the conversion is not lossless.
Manipulation of timestamps needs to be UTC end-to-end. Using FROM_UNIXTIME()
or UNIX_TIMESTAMP()
works with native UTC values on one side or the other, but the value is still converted to and from your session time zone (or the server time zone if the session time zone is not set) on the other side -- on the way to or from being a value in a TIMESTAMP
column (which is actually stored as UTC, and converted to/from your session time zone).
This is one reason why your server clock should always use UTC.
Best Answer
TIMESTAMP stores the number of seconds from 1970-01-01 00:00:01 to now. It automatically converts to the date and time format when you retrieve the data.
CURRENT_TIMESTAMP(): Returns the current date time with your timezone configured. UTC_TIMESTAMP(): Returns the current date and time using UTC timezone.
If you're using a timezone that's not UTC, these functions always return different values, equal otherwise.
MySQL always stores the date and time in UTC so it can be easily converted to different timezones. NOW() or CURRENT_TIMESTAMP() return the date/time plus your timezone configured.
UTC_TIMESTAMP() just returns the date/time ignoring your timezone setting.