Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Sumarle a una fecha - hora (timestamp) una cierta cantidad de horas (https://www.clubdelphi.com/foros/showthread.php?t=68941)

santiago14 16-07-2010 00:28:54

Sumarle a una fecha - hora (timestamp) una cierta cantidad de horas
 
Buenas, deseo que en una sql me haga la siguiente operación:
A cierta fecha (fecha y hora) le sume una cantidad de horas

Ejemplo:

15/07/2010 19:21:00 + 3 (horas) = 15/07/2010 22:21:00

¿Cómo puedo hacer esto dentro del select? Estuve probando con dateadd y no consigo buenos resultados.
Uso Firebird 2.1

gracias.

santiago14 16-07-2010 01:09:12

Bueno, conseguí solucionar el problema usando una UDF. La verdad es que funciona bien pero sería bueno si hay una forma de hacerlo sin funciones externas.
Bien, gracias.

Código SQL [-]
select rcd.fch_cobro,  rcd.fch_apertura_planilla, addhour(rcd.fch_apertura_planilla,  CAST(rve.valor as integer))
from registro_cobros_diarios rcd left outer join recupero_valor_entorno('HORAS_PLANILLA_ABIERTA') rve
    on rcd.fch_cobro = rcd.fch_cobro

Casimiro Notevi 16-07-2010 01:18:59

¿Y qué hace esa udf?

santiago14 16-07-2010 01:58:52

Cita:

Empezado por Casimiro Notevi (Mensaje 370583)
¿Y qué hace esa udf?

Simplemente le suma a una variable de tipo TIMESTAMP un valor INTEGER que se considera representa las horas.

addhour(fecha_hora, hora) --> le suma las horas a la fecha.

17/07/2010 20:52 + 3 = 17/07/2010 23:52

Casimiro Notevi 16-07-2010 02:18:45

Es que si a una timestamp (fechahora) le sumas 3, por ejemplo, se lo suma a los días, no a las horas.
Un campo fechahora es un valor como, por ejemplo: 36468,36587491222
La parte entera son los días transcurridos desde 31-12-1899 y la parte decimal corresponde a las horas.
Entonces si 1 lo divides entre 24 te da el resultado de lo que ocupa una hora, multiplicado por 3 horas, el resultado sería: 0.125
Por lo tanto, si quieres sumar 3 horas a una fechahora, debes sumar esa cantidad: now + 0.125 = fechahora dentro de 3 horas
Según tu ejemplo:
17/07/2010 20:52 + 3 = 17/07/2010 23:52

Escribo de memoria, tendría que confirmarlo, pero creo que es así.

santiago14 17-07-2010 14:31:19

Gracias compañeros, entendí.

Delphius 17-07-2010 17:05:43

Cita:

Empezado por santiago14 (Mensaje 370580)
Bueno, conseguí solucionar el problema usando una UDF. La verdad es que funciona bien pero sería bueno si hay una forma de hacerlo sin funciones externas.
Bien, gracias.

Código SQL [-]select rcd.fch_cobro, rcd.fch_apertura_planilla, addhour(rcd.fch_apertura_planilla, CAST(rve.valor as integer)) from registro_cobros_diarios rcd left outer join recupero_valor_entorno('HORAS_PLANILLA_ABIERTA') rve on rcd.fch_cobro = rcd.fch_cobro

¿Y cuál es el problema, impedimento, o motivo por el cual no aprovechar exactamente lo que ofrecen las UDF? :confused:
Dicho sea de paso: desde Firebird 2.1 ya casi no hay necesidad de registrar UDFs... ya que en su enorme mayoría vienen de "fábrica" incorporadas al motor.
Distinto es en F1.5 en donde se necesita registrarlas.
Las UDFs se estabilizaron durante el desarrollo de 2.x y además, desde (si no me falla la memoria) 2.5 se tiene pensado mejorar este punto y estandarizarlo ofreciendo los medios y herramientas para ello.

Saludos,

Casimiro Notevi 17-07-2010 23:47:11

¿Pero hay alguna que sume horas?, ¿cómo lo hace?

Delphius 19-07-2010 04:22:39

Cita:

Empezado por Casimiro Notevi (Mensaje 370738)
¿Pero hay alguna que sume horas?, ¿cómo lo hace?

Hola amigo, se me ha estado olvidando este hilo. Disculpa.

¿Me lo preguntas a mi? :confused:
Internamente pues no sabría decir como hace la UDF para sumarle las horas :o.... de que si estoy seguro es que SI EXISTE ESTA UDF... ¡Esta disponible desde F1 para Windows y desde F1.5 en Linux. ;)

Cita:

addHour

Library: fbudf
Added in: 1.0 (Win), 1.5 (Linux)
Description: Returns the first argument with number hours added. Use negative numbers to subtract.
Result type: TIMESTAMP
Syntax:
addhour (atimestamp, number)
Declaration:
DECLARE EXTERNAL FUNCTION addHour
TIMESTAMP, INT
RETURNS TIMESTAMP
ENTRY_POINT 'addHour' MODULE_NAME 'fbudf'

Fuente

¿O será que estoy interpretando mal tu pregunta? :confused: Me resulta extraño tu comentario amigo, sabiendo que tu conoces mucho de Firebird.

Saludos,

Casimiro Notevi 19-07-2010 10:44:09

Bueno, más bien me preguntaba cómo sumará horas esa función, pero ya lo he mirado, suma segundos:

Código SQL [-]
ISC_QUAD * addhour (ISC_QUAD *date, int *hours)
{
  if (!date || !hours)
    return NULL;
  else
    return addseconds(date, 60 * 60 * *hours);
}




static ISC_QUAD * addseconds (ISC_QUAD *date, int seconds)
{
    struct tm t;
    isc_decode_date(date,&t);
    t.tm_sec += seconds;
    if (t.tm_sec >= 60) {
      t.tm_min  += (t.tm_sec / 60);
      t.tm_sec ٪= 60;
      t.tm_hour += (t.tm_min / 60);
      t.tm_min ٪= 60;
      t.tm_mday += (t.tm_hour / 24);
      t.tm_hour ٪= 24;
      while (t.tm_mday > daysoftsmonth(&t)) {
        t.tm_mday -= daysoftsmonth(&t);
        t.tm_mon++;
        if (t.tm_mon > 11) {
          t.tm_mon=0;
          t.tm_year++;
        }
      }
    }
    else if (t.tm_sec < 0) {
      t.tm_min += ((t.tm_sec - 59) / 60);
      if (t.tm_sec ٪ 60 == 0) {
        t.tm_sec = (t.tm_sec ٪ 60);
      }
      else {
        t.tm_sec = (t.tm_sec ٪ 60) + 60;
      }
      if (t.tm_min < 0) {
        t.tm_hour += ((t.tm_min - 59) / 60);
        if (t.tm_min ٪ 60 == 0) {
          t.tm_min = (t.tm_min ٪ 60);
        }
        else {
          t.tm_min = (t.tm_min ٪ 60) + 60;
        }
        if (t.tm_hour < 0) {
          t.tm_mday += ((t.tm_hour - 23) / 24);
          if (t.tm_hour ٪ 24 == 0) {
            t.tm_hour = (t.tm_hour ٪ 24);
          }
          else {
            t.tm_hour = (t.tm_hour ٪ 24) + 24;
          }
          while (t.tm_mday < 1) {
            t.tm_mon--;
            if (t.tm_mon < 0) {
              t.tm_mon = 11;
              t.tm_year--;
            }
            t.tm_mday += daysoftsmonth(&t);
          }
        }
      }
    }
    return (ISC_QUAD *) gen_ib_date(&t);
}


static int daysoftsmonth(struct tm *t)
{
  int month = t->tm_mon + 1;
  int year = t->tm_year + 1900;
  return intern_daysofmonth(month, year);
}


La franja horaria es GMT +2. Ahora son las 02:07:03.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi