2014-09-18 3 views
3

У меня есть постоянный процесс, который анализирует строку в таблице базы данных и порождает дочерний процесс на некотором интервале, в зависимости от того, был ли порожден дочерний процесс (в основном, довольно простая замена CRON).Вычитание временной метки

Я изначально реализовал его, просто вычитая текущую временную метку из значения, хранящегося в столбце last_start. CURRENT_TIMESTAMP - last_start. Это показалось, что работает, однако более тщательный осмотр показал, что вычитание временной метки действовало довольно странно.

Похоже, что когда мы пересекли минутный барьер (так что текущее время отсчитывалось до новой минуты), «разность», которая была рассчитана, подскочила бы на 40 (например, от 59 до 100). Это выглядит как «1:00» - вроде - пока мы не дойдем до состояния, показанного ниже, где будет «секундная» часть его выше 60 (это пример 95 в примере ниже).

Я решил проблему, используя метод TIMESTAMPDIFF для выполнения вычитания (спасибо Stack Overflow!). Но мне непонятно, почему это было в первую очередь.

mysql db_name -e 'select CURRENT_TIMESTAMP, last_start, CURRENT_TIMESTAMP - last_start , TIMESTAMPDIFF(SECOND, last_start, CURRENT_TIMESTAMP) from tasks where id = 3'  Thu Sep 11 09:49:17 2014 

CURRENT_TIMESTAMP  last_start    CURRENT_TIMESTAMP - last_start  TIMESTAMPDIFF(SECOND, last_start, CURRENT_TIMESTAMP) 
2014-09-11 09:49:17  2014-09-11 09:37:22 1195         715 

Может кто-нибудь объяснить мне, что происходит, когда я просто вычитаю временные метки, как я это делал?

Edit: Схема таблицы выглядит следующим образом:

CREATE TABLE `tasks` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `task` char(128) NOT NULL, 
    `run_count` int(10) unsigned NOT NULL DEFAULT '0', 
    `domina` char(128) DEFAULT NULL, 
    `slave` char(128) DEFAULT NULL, 
    `last_start` timestamp NULL DEFAULT NULL, 
    `last_end` timestamp NULL DEFAULT NULL, 
    `avg_duration` int(10) unsigned NOT NULL DEFAULT '0', 
    `last_status` char(64) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 
+0

Каков тип данных 'last_start'? MySQL может быть забавным при работе с датами и временем, которые не хранятся в родных типах. –

+0

Добавлен оператор create table – v4nz

+1

Используйте 'timestampdiff()' вместо '-'. '-' обрабатывает аргументы как целые числа, что вызывает вашу проблему. –

ответ

2

Почему это происходит не так? Ну, вы ожидаете, что база данных (или любой другой программный продукт), которая имела тип данных, называемый TIMESTAMP, и «константа» под названием CURRENT_TIMESTAMP, будет представлять последнюю, используя прежнюю.

Но нет. Это не MySQL. CURRENT_TIMESTAMP является синонимом для now(), тип которого зависит от контекста. К счастью, документация объясняет это совершенно ясно:

Возвращает текущую дату и время как значение «YYYY-MM-DD HH: MM: SS» формате или ГГГГММДДЧЧММСС, в зависимости от того, используется ли функция в строка или числовой контекст.

Конечно, вам нужно выяснить, каковы различные контексты. Намек. Использование - является «числовым контекстом».

Что происходит, так это следующее. MySQL видит CURRENT_TIMESTAMP и помещает в текущее время. Но как? Он видит - и определяет, что он входит в число. Затем наступает last_start. Ну, теперь это тоже нужно преобразовать в число. И угадай что? Вы получаете фанковое поведение.

+0

'будет представлять последний, используя прежний' замечательный (и удивительный полный) –

Смежные вопросы