Power Builder - COMO OBTENER NUMERO DE AÑOS ENTRE DOS FECHAS

 
Vista:

COMO OBTENER NUMERO DE AÑOS ENTRE DOS FECHAS

Publicado por Julio Cesar (86 intervenciones) el 19/12/2007 13:14:29
Buenos días
Necesito obtener el numero de años entre dos fechas vale decir la fecha actual debo restarle la fecha en que ingreso el trabajador y este resultado debe ser en años
Ejemplo
Hoy estamos a 19/12/2007
Ingreso a trabajar el 01/12/2005
Resultado 2 Años
Si el resultado da por ej. 1.5 es posible redondearlo a 2, si tiene menos de un año y el resultado es 0.5 debe quedar igual
De ante manos muchas gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:COMO OBTENER NUMERO DE AÑOS ENTRE DOS FECHAS

Publicado por alberto (73 intervenciones) el 19/12/2007 14:14:48
Te paso unas funciones hechas en C (podés compilar con gcc o con borland C) que permiten procesamiento de fechas. Las había hecho para el motor firebird pero se pueden acceder desde powerbuilder vía EXTERNAL FUNCTION.
Como recibe ciertos argumentos particulares de Firebird, pudes cambias las estructuras por las normales de Fecha / Hora / Timestamp (debería recibir una estructura de tipo estructura tm en lugar de ISC_DATE o ISC_TIMESTAMP). Esto lo cambiás fácilmente. Fíjate particularmente en el método F_DATEDIFF

También te paso links de un algoritmo llamado RATADIE, que sirve para cálculos de fechas. Solución fácil y elegante para este tipo de problemas.

Espero que te ayude.

/********************************************************
FUNCIONES DE FECHA / HORA
******************************************************/
/* Replace "datetime.h" with the name of your header */
#include <time.h>
#include <ib_util.h>
#include <ibase.h>
#include <windows.h>
#include "datetime.h"
#include <string.h>

/***********************************************
F_DATEPART
***********************************************/
DLLIMPORT int *f_datepart(ISC_DATE *adt_date,const char *as_datepart)
{
struct tm ldt_date;
int li_result = -1;

isc_decode_sql_date(adt_date,&ldt_date);

//año
if (!strcmp(as_datepart,"yy"))
{
li_result = ldt_date.tm_year + 1900; //pq retorna la cantidad de años desde 1900
return (int *) li_result;
}
//mes
if (!strcmp(as_datepart,"mm"))
{
li_result = ldt_date.tm_mon + 1; //pq retorna de 0 a 11 meses desde enero
return (int *) li_result;
}
//dia real
if (!strcmp(as_datepart,"md"))
{
li_result = ldt_date.tm_mday;
return (int *) li_result;
}
//día de la semana
if (!strcmp(as_datepart,"dw"))
{
li_result = ldt_date.tm_wday;
return (int *) li_result;
}
//día del año
if (!strcmp(as_datepart,"dy"))
{
li_result = ldt_date.tm_yday;
return (int *) li_result;
}

return (int *) li_result;
};

/***********************************************
F_DATETIMEPART
************************************************/

DLLIMPORT int *f_datetimepart(ISC_TIMESTAMP *adt_datetime,const char *as_datepart)
{
struct tm ldt_datetime;
int li_result = -1;

isc_decode_timestamp(adt_datetime,&ldt_datetime);

//año
if (!strcmp(as_datepart,"yy"))
{
li_result = ldt_datetime.tm_year + 1900; //pq retorna la cantidad de años desde 1900
return (int *) li_result;
}
//mes
if (!strcmp(as_datepart,"mm"))
{
li_result = ldt_datetime.tm_mon + 1; //pq retorna de 0 a 11 meses desde enero
return (int *) li_result;
}
//dia real
if (!strcmp(as_datepart,"md"))
{
li_result = ldt_datetime.tm_mday;
return (int *) li_result;
}
//día de la semana
if (!strcmp(as_datepart,"dw"))
{
li_result = ldt_datetime.tm_wday;
return (int *) li_result;
}
//día del año
if (!strcmp(as_datepart,"dy"))
{
li_result = ldt_datetime.tm_yday;
return (int *) li_result;
}
//hora
if (!strcmp(as_datepart,"hh"))
{
li_result = ldt_datetime.tm_hour;
return (int *) li_result;
}
//minuto
if (!strcmp(as_datepart,"mi"))
{
li_result = ldt_datetime.tm_min;
return (int *) li_result;
}
//segundo
if (!strcmp(as_datepart,"ss"))
{
li_result = ldt_datetime.tm_sec;
return (int *) li_result;
}

return (int *) li_result;
};

/***********************************************
F_LEAPYEAR
************************************************/
DLLIMPORT int *f_leapyear(int *ai_year)
{
int li_return;

if (*ai_year % 4 != 0)
li_return = 0;
else if ((*ai_year % 100 == 0) && (!(*ai_year % 400 == 0)))
li_return = 0;
else
li_return = 1;

return (int *) li_return;
};

/***********************************************
F_MONTHDAYCOUNT
************************************************/
DLLIMPORT int *f_monthdaycount(int *ai_year, int *ai_month)
{
int li_leap;
int li_return;

li_leap = (int)f_leapyear(ai_year);

switch (*ai_month)
{
case 1: li_return = 31; break;
case 2: { li_return = (li_leap == 1 ? 29 : 28); break; }
case 3: li_return = 31; break;
case 4: li_return = 30; break;
case 5: li_return = 31; break;
case 6: li_return = 30; break;
case 7: li_return = 31; break;
case 8: li_return = 31; break;
case 9: li_return = 30; break;
case 10: li_return = 31; break;
case 11: li_return = 30; break;
case 12: li_return = 31; break;
default: li_return = -1;
}
return (int *) li_return;
};

/***********************************************
F_DATEDIFF
************************************************/
DLLIMPORT int *f_datediff(ISC_DATE *ad_date1,
ISC_DATE *ad_date2,
const char *as_datepart)
{
struct tm ld_date1;
struct tm ld_date2;
long ll_result;
int li_monthdaycount;
int *li_tempyear;
int *li_tempmonth;
//contenedores de resultados
int li_resultday;
int li_resultmonth;
int li_monthoffset = 0;
int li_resultyear;
int li_resulterror = -1;

if (!ad_date1)
{
return (int *) li_resulterror;
};
if (!ad_date2)
{
return (int *) li_resulterror;
};
isc_decode_sql_date(ad_date1,&ld_date1);
isc_decode_sql_date(ad_date2,&ld_date2);


/*calcular el día
If %DAY(DATE2) <= %DAY(DATE1) ;
then %DAY(RESULT) = %DAY(DATE1) - %DAY(DATE2).
If %DAY(DATE2) > %DAY(DATE1) ;
then %DAY(RESULT) = N + %DAY(DATE1) - %DAY(DATE2) ;
where N = the last day of %MONTH(DATE2). ;
%MONTH(DATE2) is then incremented by 1.*/

if (ld_date2.tm_mday <= ld_date1.tm_mday)
{
li_resultday = ld_date1.tm_mday - ld_date2.tm_mday;
}

if (ld_date2.tm_mday > ld_date1.tm_mday)
{
li_tempyear = &ld_date2.tm_year;
li_tempmonth = &ld_date2.tm_mon;
li_monthdaycount = *f_monthdaycount(li_tempyear,li_tempmonth);
li_resultday = li_monthdaycount + ld_date1.tm_mday - ld_date2.tm_mday;
// ld_date2.tm_mon += 1;
}


/*calcular el mes
If %MONTH(DATE2) <= %MONTH(DATE1) ;
then %MONTH(RESULT) = %MONTH(DATE1) - %MONTH(DATE2).
If %MONTH(DATE2) > %MONTH(DATE1) ;
then %MONTH(RESULT) = 12 + %MONTH(DATE1) - %MONTH(DATE2). ;
%YEAR(DATE2) is then incremented by 1.
*/
if (ld_date2.tm_mon <= ld_date1.tm_mon)
{
li_resultmonth = ld_date1.tm_mon - ld_date2.tm_mon;
}

if (ld_date2.tm_mon > ld_date2.tm_mon)
{
li_resultmonth = 12 + ld_date1.tm_mon - ld_date2.tm_mon;
ld_date2.tm_year += 1;
}

/*calcular el año
%YEAR(RESULT) = %YEAR(DATE1) - %YEAR(DATE2).
*/
li_resultyear = ld_date1.tm_year - ld_date2.tm_year;

//ver que parte retornar
if (!strcmp(as_datepart,"d"))
{
return (int *) li_resultday;
}
if (!strcmp(as_datepart,"m"))
{
return (int *) li_resultmonth;
}
if (!strcmp(as_datepart,"a"))
{
return (int *) li_resultyear;
}

return (int *) li_resulterror;

};


/***********************************************
F_DATETIMEDIFF
************************************************/
/*DLLIMPORT int *f_datediff(ISC_TIMESTAMP *adt_datetime1,
ISC_TIMESTAMP *adt_datetime2,
const char *as_datepart)
{
struct tm ldt_datetime1;
struct tm ldt_datetime2;
long ll_result;
int li_resultday;
int li_monthdaycount;
int *li_tempyear;
int *li_tempmonth;

isc_decode_timestamp(adt_datetime1,&ldt_datetime1);
isc_decode_timestamp(adt_datetime2,&ldt_datetime2);




if (ldt_datetime2.tm_mday <= ldt_datetime1.tm_mday)
{
li_resultday = ldt_datetime1.tm_mday - ldt_datetime2.tm_mday;
}

if (ldt_datetime2.tm_mday > ldt_datetime1.tm_mday)
{
li_tempyear = (int *) ldt_datetime2.tm_year;
li_tempmonth = (int *) ldt_datetime2.tm_mon;
li_monthdaycount = (int) f_monthdaycount(li_tempyear,li_tempmonth);
li_resultday = li_monthdaycount + ldt_datetime1.tm_mday - ldt_datetime2.tm_mday;
}

return (int *) li_resultday;

}; */


BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;

case DLL_PROCESS_DETACH:
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;
}

/* Returns TRUE on success, FALSE on failure */
return TRUE;
}

/*************************************************************
PÁGINAS CON ALGORITMO RATADIE
Y ALGUNOS COMENTARIOS
************************************************************/
http://www.capecod.net/~pbaum/date/date0.htm
http://www.capecod.net/~pbaum/date/rata.htm
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

GRACIAS ALBERTO POR TU COOPERACION

Publicado por Julio Cesar (86 intervenciones) el 20/12/2007 13:26:07
Muy agradecido Alberto por tu apoyo en este tema, la verdad que encontré la solución a mi problema y es mas simple de lo que pensé en un momento, le dejo el código a las personas que lo necesiten es muy simple

vl_agnos = Daysafter(vl_fec_ing,today())
vl_agnos = vl_agnos / 365
IF vl_agnos < 365 THEN
vl_agnos = 0
ELSE
vl_agnos = vl_agnos / 365
END IF
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar