2010-08-14 8 views
2

Un peu d'un puzzle pour vous les gars. Je peux trouver une solution contondante (ci-dessous), mais je pensais que cela vous présenterait à tous pour voir s'il y avait une solution plus élégante là-bas. Gardez à l'esprit que je suis à la recherche d'une solution PHP ou MySql seulement.MySQL ajouter du temps à la colonne

Les tables sont des 'bougies2'. J'ai une colonne de temps de MySQL TEXT qui a un datestamp dedans (par exemple 2010.08.13 19:30). S'il vous plaît ne demandez pas pourquoi c'est un champ de texte :). J'ai une deuxième colonne TEXT 'timeframe' qui liste une dénomination de temps (par exemple '15m', '30m', '1h', '4h' ou 'daily'). 'id' est la clé primaire.

Je souhaite ajouter la durée dans 'timeframe' à 'time'. Ainsi par exemple si 'time' == '2010.08.13 19:30' et 'timeframe' == 15m alors il mettrait à jour 'time' avec '2010.08.13 19:45' (notez l'ajout de 15 minutes) minutes).

Voici ce que je pensais:

// PHP interroger la base de données:

//using UNIX_TIMESTAMP to make the datetime usable by PHP 
$sql = "SELECT UNIX_TIMESTAMP(time), timeframe, id FROM candles2"; 
$result = mysql_query($sql); 

//loop through rows 
while($row = mysql_fetch_array($result)) 
{ 
//call function to determine the appropriate # of seconds to add 
$newTime = newTime($row['time'],$row['timeframe']); 

//build UPDATE query and update row 
$update_query = "UPDATE candles2 SET 'time'= FROM_UNIXTIME(" . $newTime . ") WHERE id='".$row['id']."'"; 
$update_result = mysql_query($update_query); 
} 

// Fonction PHP pour ajouter secondes appropriées

function newTime($oldtime,$timeframe) 
{ 
switch ($timeframe) 
    { 
     case "15m": return($oldtime + 15 * 60); 
case "30m": return($oldtime + 30 * 60); 
     case "1h": return($oldtime + 60 * 60); 
case "4h": return($oldtime + 240 * 60); 
case "daily":   return($oldtime + 1440 * 60); 
default:   die("whoops, something broke"); 
    } 
} 

Répondre

1

Pourquoi ne pas utiliser MySQL de STR_TO_DATE() à transformer votre valeur de texte en une valeur de date-heure, puis utiliser DATE_ADD() pour ajouter l'intervalle? Il devrait être assez facile de transformer votre calendrier en un format d'intervalle que MySQL attend (INTERVAL 30 MINUTE par exemple). Vous pouvez ensuite utiliser DATE_FORMAT() pour le récupérer sous forme de texte.

0

changer votre fonction NEWTIME à ce qui suit:

function newTime($oldtime,$timeframe) 
{ 
    $new_time = strtotime($oldtime); 

    switch ($timeframe) 
    { 
    case "15m": 
     $new_time = $new_time + 15 * 60; 
     break; 

    case "30m": 
     $new_time = $new_time + 30 * 60; 
     break; 

    case "1h": 
     $new_time = $new_time + 60 * 60; 
     break; 

    case "4h": 
     $new_time = $new_time + 240 * 60; 
     break; 

    case "daily": 
     $new_time = $new_time + 1440 * 60; 
     break; 
    } 

    return date('Y.m.d H:i', $new_time); 
} 
0

Vous pouvez utiliser le PHP DateTime class pour effectuer les calculs de date et d'heure beaucoup plus simple:

$timeframe = '15m'; 
$time = '2010.08.13 19:30'; 

$dt = DateTime::createFromFormat('Y.m.d G:i', $time); 
$new_dt = $dt->add(
    new DateInterval('PT' . strtoupper(
    str_replace('daily', '24h', $timeframe)))); 

echo date_format($new_dt, 'Y.m.d G:i'); 
// 2010.08.13 19:45 

Ou, pour une solution purement MySQL, vous pourriez utilisez un curseur pour créer une instruction préparée pour mettre à jour les lignes:

DELIMITER // 
DROP PROCEDURE IF EXISTS update_candles// 
CREATE PROCEDURE update_candles() 
BEGIN 
    DECLARE var_id INT; 
    DECLARE var_time, var_timeframe TEXT; 

    DECLARE var_done INT DEFAULT 0; 
    DECLARE csr_candles CURSOR FOR 
    SELECT id, time, timeframe FROM candles2; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET var_done = 1; 

    OPEN csr_candles; 

    REPEAT 
    FETCH csr_candles INTO var_id, var_time, var_timeframe; 
    IF NOT var_done THEN 
     SET 
     @id  := var_id, 
     @time  := var_time, 
     @timeframe := var_timeframe, 
     @unit1  := SUBSTR(@timeframe, -1), 
     @unit2  := MAKE_SET(FIND_IN_SET(@unit1, 'm,h,,y'), 'MINUTE', 'HOUR', 'DAY'), 
     @interval := FORMAT(@timeframe, 0) | 1, 
     @var_sql := CONCAT('UPDATE candles2 SET time = TIMESTAMPADD(', @unit2, ',?,?) WHERE id = ?'); 

     PREPARE sql_stmt FROM @var_sql; 
     EXECUTE sql_stmt USING @interval, @time, @id; 
    END IF; 
    UNTIL var_done END REPEAT; 

    DEALLOCATE PREPARE sql_stmt; 
END; 
// 
DELIMITER ; 

CALL update_candles; 
Questions connexes