Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: помогите с TIMESTAMP
 
 автор: Binura   (19.07.2007 в 00:56)   письмо автору
 
 

в общем мне нужно сделать время добавления и время обновления записи....
как лучше сделать?

   
 
 автор: Trianon   (19.07.2007 в 01:14)   письмо автору
 
   для: Binura   (19.07.2007 в 00:56)
 

сли timestamp-поле в таблице единственное, и если Вы не указали обратного - оно само будет так себя вести.
можно прописать явно - как-то так:

stamp TIMESTAMP 
   NOT NULL 
   DEFAULT CURRENT_TIMESTAMP 
   ON UPDATE CURRENT_TIMESTAMP, ....

   
 
 автор: Binura   (19.07.2007 в 01:38)   письмо автору
 
   для: Trianon   (19.07.2007 в 01:14)
 

Вот мне нужно. без всяких умолчаний =)

дата добавления, дата обновления записи,

и как правильно сделать запись и обновление?

чтоб не получилось 0000-00-00 000000.

   
 
 автор: Trianon   (19.07.2007 в 09:28)   письмо автору
 
   для: Binura   (19.07.2007 в 01:38)
 

>Вот мне нужно. без всяких умолчаний =)

Что Вы хотели сказать этой фразой?


>дата добавления, дата обновления записи,

Нужны два независимых поля?
Тогда лучше сделать чуть иначе.
Поле добавления выбрать типом DATETIME и при добавлении записи указывать его явно

CREATE TABLE tbl(
  id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  create_stamp DATETIME NOT NULL,
  update_stamp TIMESTAMP NOT NULL
     DEFAULT CURRENT_TIMESTAMP  
     ON UPDATE CURRENT_TIMESTAMP,
  anyfield VARCHAR(255) NULL
)



>и как правильно сделать запись

INSERT INTO tbl 
    (create_stamp, anyfield) 
  VALUES (NOW(), 'anydata')


> и обновление?

UPDATE tbl 
    SET
      anyfield ='anydata'


и выборку

SELECT * FROM tbl

>чтоб не получилось 0000-00-00 000000.
не получится.

   
 
 автор: Binura   (19.07.2007 в 18:35)   письмо автору
 
   для: Trianon   (19.07.2007 в 09:28)
 

>

>CREATE TABLE tbl(
>  id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
>  create_stamp DATETIME NOT NULL,
>  update_stamp TIMESTAMP NOT NULL
>     DEFAULT CURRENT_TIMESTAMP  
>     ON UPDATE CURRENT_TIMESTAMP,
>  anyfield VARCHAR(255) NULL
>)
>


я сделал так

 `oldtime` timestamp NOT NULL default '0000-00-00 00:00:00', 
 `newtime` timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP,


вроде все работает... так пойдет?

при записи:
'oldtime' - NOW()
newtime - будет по умолчанию "0000-00-00 000000"

при обновлении
'oldtime' - не изменится
newtime - получит CURRENT_TIMESTAMP


я прально сделала?

   
 
 автор: Trianon   (19.07.2007 в 19:23)   письмо автору
 
   для: Binura   (19.07.2007 в 18:35)
 

можно и так.

   
 
 автор: Binura   (19.07.2007 в 20:16)   письмо автору
 
   для: Trianon   (19.07.2007 в 19:23)
 

а как вывести точную разницу?
т.е. между `oldtime` и `newtime` или NOW()/
в формате d H:i:s

   
 
 автор: Binura   (19.07.2007 в 22:04)   письмо автору
 
   для: Binura   (19.07.2007 в 20:16)
 

никто не знает? =(

   
 
 автор: Unkind   (19.07.2007 в 22:28)   письмо автору
 
   для: Binura   (19.07.2007 в 22:04)
 

Я не гуру в MySQL, поэтому не могу утверждать, что на MySQL это нельзя сделать.

SELECT TIMESTAMPDIFF(SECOND, `oldtime`, `newtime`) FROM `tbl`;



<?php
function maketime($s)
{
    return 
sprintf("%d %02d:%02d:%02d", (int)($s 86400), (int)($s 3600) % 24, (int)($s 60) % 60$s 60);
}

//В сутках 86400 секунд
echo(maketime(86400 1)); //1 00:00:01
?>


В данном случае вычисляется разница в секундах между двумя датами. После нужно эту разницу использовать, как аргумент функции maketime().

P.S. MySQL-функция для MySQL >= v 5.0

   
 
 автор: Trianon   (19.07.2007 в 22:53)   письмо автору
 
   для: Unkind   (19.07.2007 в 22:28)
 


SELECT 
  CONCAT(
   ((UNIX_TIMESTAMP(newtime)-UNIX_TIMESTAMP(oldtime)) DIV 86400),'  ',
   SEC_TO_TIME((UNIX_TIMESTAMP()-UNIX_TIMESTAMP(stamp)) MOD 86400)) as dif 
FROM tbl 


Эта громоздкая конструкция пойдет и на младших серверах.

   
 
 автор: Binura   (19.07.2007 в 23:05)   письмо автору
 
   для: Trianon   (19.07.2007 в 22:53)
 

ОГО.... может можно по другому? неужели нельзя сделать как-нибудь в таком виде:

DATE_FORMAT((NOW()-oldtime),'%d %H:%s:%i') AS putdate FROM

   
 
 автор: Unkind   (19.07.2007 в 23:30)   письмо автору
 
   для: Binura   (19.07.2007 в 23:05)
 

Очень интересно Вы оперируете датами в формате "YYYY-MM-DD H:i:s".
Хоть они в данном случае и будут уже в виде "YYYYMMDDHis", но, во-первых, функция DATE_FORMAT() принимает как первый аргумент дату в формате "YYYY-MM-DD H:i:s", а, во-вторых, это будет просто неверно. Это не десятичные числа.

   
 
 автор: Binura   (19.07.2007 в 23:36)   письмо автору
 
   для: Unkind   (19.07.2007 в 23:30)
 

я знаю что это не верно =)
если бы ЭТО работало я бы не спрашивала... мне нужно что нибудь в таком роде....

или лучше получить секунды а в php уже получить время...?
но тоже не понятно... т.е. если я сделаю так

$w = date('d H-i-s',$sec);

работает, но если будет больше 24 часов мне d покажет день, который Бог знает когда был... а мне надо 1 день 20часов 34мин 32сек.

   
 
 автор: Unkind   (19.07.2007 в 23:39)   письмо автору
 
   для: Binura   (19.07.2007 в 23:36)
 

А Вы вообще мой пост (19.07.2007 в 22:28) читали?

   
 
 автор: Binura   (19.07.2007 в 23:53)   письмо автору
 
   для: Unkind   (19.07.2007 в 23:39)
 

да читала, но я думаю примерно сделать так

if($s<=86400)
{$d = floor($s/86400);}
$time = date('H:i:s',$s);

думаю ошибки не будет, да и мне легче работать...

   
 
 автор: Unkind   (20.07.2007 в 00:04)   письмо автору
 
   для: Binura   (19.07.2007 в 23:53)
 

Ну это, конечно, Вы напрасно так думаете.
Это время с учетом часового пояса.
И, если не секрет, чем вариант Trianon'а не устраивает?

   
 
 автор: Binura   (20.07.2007 в 00:18)   письмо автору
 
   для: Unkind   (20.07.2007 в 00:04)
 

=) пока этого мне хватит потом при необходимости переделаю...

   
 
 автор: Unkind   (20.07.2007 в 00:37)   письмо автору
 
   для: Binura   (20.07.2007 в 00:18)
 

А че скромничать? За это с Вас деньги же не потребуют.

Ваш вариант неправильный. Как может устраивать что-то неправильное?

   
 
 автор: Trianon   (20.07.2007 в 00:50)   письмо автору
 
   для: Binura   (19.07.2007 в 23:53)
 

>да читала, но я думаю примерно сделать так
>

>if($s<=86400)
>{$d = floor($s/86400);}
>$time = date('H:i:s',$s);
>

>думаю ошибки не будет, да и мне легче работать...

это неправильно.
Функция date принимает абсолютный момент времени, а не интервал.
Попробуйте вывести echo date('H:i:s',10*3600); и увидите отнюдь не 10 часов.

В конце концов, не так сложно написать функцию, которая преобразует именно интервал.

   
 
 автор: Binura   (20.07.2007 в 17:09)   письмо автору
 
   для: Trianon   (20.07.2007 в 00:50)
 

я увидела 10 часов.... мне из date не нужно точная дата. date как бы находится 1января 1970года 00:00:00.. и вот прошло 10*3600 и он показал 10 часов. прошло 10*3600*24 он все равно покажет 10часов это мне и нужно...

   
 
 автор: Trianon   (20.07.2007 в 17:25)   письмо автору
 
   для: Binura   (20.07.2007 в 17:09)
 

Это сегодня Вы видите 10 часов. Случайно.
А потом в октябре кончится летнее время - и увидите только девять.
А потом в марте опять начнется - и опять будет 10.
А потом сервер переедет в Монреаль и будет 3.
Вам нужна такая дерготня?

   
 
 автор: Binura   (20.07.2007 в 18:00)   письмо автору
 
   для: Trianon   (20.07.2007 в 17:25)
 

хорошо....
а как с этим работать? =)

SELECT  
  CONCAT( 
   ((UNIX_TIMESTAMP(newtime)-UNIX_TIMESTAMP(oldtime)) DIV 86400),'  ', 
   SEC_TO_TIME((UNIX_TIMESTAMP()-UNIX_TIMESTAMP(stamp)) MOD 86400)) as dif  
FROM tbl 


что делает CONCAT()?

я так поняла это только для дней, а как часы и минуты сделать?

   
 
 автор: Trianon   (20.07.2007 в 19:16)   письмо автору
 
   для: Binura   (20.07.2007 в 18:00)
 

Вы неправильно поняли. Этот оператор формирует всё что Вам нужно.
<?
$sql 

SELECT  
        tbl.*, 
        CONCAT(  
         ((UNIX_TIMESTAMP(newtime)-UNIX_TIMESTAMP(oldtime)) DIV 86400),'  ',  
         SEC_TO_TIME((UNIX_TIMESTAMP()-UNIX_TIMESTAMP(stamp)) MOD 86400)) as dif  
  FROM tbl  
"
;

$res mysql_query($sql);
while(
$row mysql_fetch_assoc($res))
{
    echo 
'<pre>';
    
print_r($row);
    echo 
'</pre>';
}

   
 
 автор: Trianon   (20.07.2007 в 19:24)   письмо автору
 
   для: Binura   (20.07.2007 в 18:00)
 

Да, забыл сказать. CONCAT (a, b, c, d) это всё равно что в php $a . $b . $c . $d

В конце концов, если Вам не нравится вычислять строку средствами SQL
можете написать функцию перевода.

function human_interval($sec)
{
    $dsec = $sec % (24*3600);
    $days = ($sec - $dsec)/ (24*3600);
 
    $min = $dsec % 3600;

    $hour = ($dsec-$min)/3600;
    $sec = $min %60;
    $min = ($min-$sec)/60;
    return sprintf("%d %02d:%02d:%02d", $days, $hour, $min,  $sec);
}

и обращаться к ней вместо date

   
 
 автор: Binura   (20.07.2007 в 19:50)   письмо автору
 
   для: Trianon   (20.07.2007 в 19:24)
 

вот спасибо... =) пошла тестировать..
но вот еще вопросик, на счет UPDATE...
как сделать?

мне нужно обновить только одно поле, и то это поле
`ntime` TIMESTAMP NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP ,

т.е. я не обновляю поля, надо чтоб скрипт сам обновил время,
как то так...
UPDATE `online` WHERE `id`='$ID'

   
 
 автор: Trianon   (20.07.2007 в 20:00)   письмо автору
 
   для: Binura   (20.07.2007 в 19:50)
 

присвойте ему значение напрямую.

UPDATE `online` 
   SET ntime=NOW() 
WHERE `id`='$ID'

   
 
 автор: Binura   (20.07.2007 в 20:18)   письмо автору
 
   для: Trianon   (20.07.2007 в 20:00)
 

тогда можно не использовать
on update CURRENT_TIMESTAMP
=(

   
 
 автор: Binura   (20.07.2007 в 20:23)   письмо автору
 
   для: Binura   (20.07.2007 в 20:18)
 


$sql = "  
SELECT   
        tbl.*,  
        CONCAT(   
         ((UNIX_TIMESTAMP(newtime)-UNIX_TIMESTAMP(oldtime)) DIV 86400),'  ',   
         SEC_TO_TIME((UNIX_TIMESTAMP()-UNIX_TIMESTAMP(stamp)) MOD 86400)) as dif   
  FROM tbl   
";


что то я не могу такой запрос сделать...

таблица online
oldtime
newtime

как прально сделать запрос?

   
 
 автор: Trianon   (20.07.2007 в 20:28)   письмо автору
 
   для: Binura   (20.07.2007 в 20:23)
 

извините. Ошметки от проверочных действий вкрались.


$sql = "   
SELECT    
        online.*,   
        CONCAT(    
         ((UNIX_TIMESTAMP(newtime)-UNIX_TIMESTAMP(oldtime)) DIV 86400),'  ',    
         SEC_TO_TIME((UNIX_TIMESTAMP(newtime)-UNIX_TIMESTAMP(oldtime)) MOD 86400)) as dif    
  FROM online    
"; 

   
 
 автор: Binura   (20.07.2007 в 20:43)   письмо автору
 
   для: Trianon   (20.07.2007 в 20:28)
 

все работает...

но хотелось бы еще

1) убрать секунды

2) если день и часы равны 0 то их не выводить...

это возможно? =)

   
 
 автор: Trianon   (20.07.2007 в 21:46)   письмо автору
 
   для: Binura   (20.07.2007 в 20:43)
 

возможно. Но лучше на php.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования