Comparto esta idea con ustedes, por si a alguien le es útil (y de paso,
por qué no, si alguien tiene una solución más elegante a mano y me
ilumina).

Me han pedido (entre otras cosas) hallar cuántos de los trabajadores
almacenados en una base de datos (PostgreSQL, por más señas) son menores
de 40 años.

Si voy a programar en PHP, que es lo que usamos acá, disponiendo de la
fecha de nacimiento y conociendo la fecha corriente, se puede hallar la
diferencia en años, meses y días usando soluciones como esta:

$fecha1=new DateTime(primerafecha);

$fecha2=new DateTime(segundafecha);
$intervalo=$fecha2-> diff ($fecha1);

$cinterv=$intervalo->format(‘%Y-%m-%d’);

$c=split(“-“,$cinterv);

$cdias=$c[2];

$cmeses=$c[1];

$canos=$c[0];

Donde $cdias, $cmeses y $canos son respectivamente las cantidades de
días, meses y años entra las dos fechas.

Lo interesante es que en esa base no se han almacenado la fechas de
nacimiento, sino solamente el número del carnet de identidad. Esto
complica el cuadro. Veamos: en el número del carnet de identidad los
primeros 6 dígitos indican año, mes y día. Desconozco si alguno de los
siguientes dígitos apunta inequívocamente a la fecha, así que debo
basarme solamente en el dato de estos primeros 6. Por ejemplo, 551002
indica 1955 (no inequívocamente, si me baso solo en eso), el 10 señala a
octubre y el 02 denota el día 2. El año se toma como 1955; ello es en el
entendido de que el 55 inicial no se va a referir a 2055, que no hemos
llegado todavía a esa fecha.

Una solución “quick and dirty” (rápida y sucia) para determinar los
menores de 40 pudiera ser:

(Pongo solo la parte relevante del código)

$jaro=round(date(‘Y’),0);

$monato=round(date(‘m’),0);

$tago=round(date(‘d’),0);

$datos=pg_query($mibase,”select nombre as nombre,ape1 as ape1,nivel as
nivel,ci as ci

into talla_joven_fumero
from datosgenerales
where baja=’f’ and numero<5000 and (numero>8999 or numero<9700) and
(($jaro -(1900+((substr(ci,1,2))::numeric))<40) or ($jaro -(1900
+((substr(ci,1,2))::numeric))=40 and (substr(ci,3,2)::numeric)>$monato)
or
($jaro -(1900+((substr(ci,1,2))::numeric))=40 and
(substr(ci,3,2)::numeric)=$monato and (substr(ci,5,2)::numeric)>$tago) )
order by ci”);

El query $datos extrae el nombre, los dos apellidos, el nivel de
escolaridad y el número de carnet de identidad de los trabajadores
menores de 40 años desde una supuesta base datosgenerales  e inserta los
datos en otra, temporal, llamada talla_joven_fumero. Una vez que los
tengo ahí, puedo determinar otras cosas que me piden (sexo, nivel de
escolaridad) y que ahora no interesan.

Explicando un poco: de la fecha actual (que la da la función date)
extraigo año, mes y día porque me harán falta en el query. Redondeo para
obtener valores enteros.

Es imprescindible que el trabajador no haya sido baja (hay que guardar
los datos de las bajas durante un tiempo), por tanto se requiere que el
campo “baja”, que es booleano, tenga valor FALSE. El rejuego con el
rango de números de trabajador se debe a que algunos rangos están
destinados a otros menesteres.

El número de identidad está almacenado como texto, de modo que al
analizarlo le pedimos al PostgreSQL que cuando extraiga la subcadenas
correspondientes al año, mes y día interprete el dato extraído como
numérico, para poder sacar la cuenta. La especificación order by hace
que el resultado que se inserta en la tabla temporal sea ordenado de
mayor edad a menor edad.

Ahora bien, esta solución exige varias suposiciones de partida. Debo
conocer la fecha corriente (obvio) y en la cuenta sumo 1900 porque estoy
asumiendo que si la edad mínima para trabajador son 17 años, aún no
tengo en nómina trabajadores nacidos a partir del 2000. También asumo,
obviamente, que ninguno de nuestros trabajadores nació en el siglo XIX… 

Entonces debo razonar que cuando pasen unos años no podré programar tan
alegremente; en cuanto tenga el primer trabajador nacido a partir del
2000 ya no se podrá sumar siempre 1900 a los dos primeros dígitos del
número del carnet de identidad, pues si bien es verdad que resultaría
difícil asumir que una persona de 100 años se mantiene trabajando, ello
no es imposible. .. tengo una vecina de 103 años muy coherente, que aún
cose…

Pero bueno. Debo asumir que a esas edades ya no está en nómina, o esto
se complica.

Así que una solución más completa, que no caduque en pocos años, debería
razonar algo como esto: para fechas de cuatro dígitos (no espero vivir
para ver las de 5, así que no me esfuerzo más), si los dos primeros
dígitos del número de carnet de identidad son menores que los dos
últimos dígitos del año corriente, le sumo los dos primeros dígitos del
año corriente, terminando con 00 y convertido en número para hacer la
cuenta; si no es así, o sea, son mayores, le resto una unidad a los
primeros dos dígitos del año corriente, le empato al final 00 y lo
convierto a número para hacer la suma.

Si se les ocurre una solución mejor, ya saben donde escribirme…
-- 
M.Sc. Alberto García Fumero
Usuario Linux 97 138, registrado 10/12/1998
http://interese.cubava.cu
Una conclusión es el punto en que usted se cansó de pensar.



______________________________________________________________________
Lista de correos del Grupo de Usuarios de Tecnologías Libres de Cuba.
Gutl-l@jovenclub.cu
https://listas.jovenclub.cu/cgi-bin/mailman/listinfo/gutl-l

Responder a