Indice
1. Se
busca un experto
2. Introducción
3. Definiciones
Basicas
4. Descripción de las
funciones
5. Conclusión
Las funciones que
más adelante se explican fueron desarrolladas por
mí durante la primera mitad de los años ochenta,
cuando me desempeñaba como instructor de BASIC. Para
entonces, la validación de fechas requería de una
subrutina que contenía una serie de comparaciones
lógicas con abundantes IF, OR, XOR y hasta tablas cargadas
en una DATA. Con el uso de las funciones
eliminé la subrutina y reduje el uso de las funciones
lógicas a unos cuatro (04) IF, solamente.
Para la época mencionada no era fácil dar a conocer
los resultados de una investigación; sobre todo para alguien que,
como yo, no tenía otro deseo diferente al de apoyar a sus
alumnos y a sus colegas instructores.
Por razones laborales, a principios del
año 87 dejé la programación y el oficio de instructor de
lenguajes de computación; actividad que retomé en
el año 2000, cuando dos jóvenes me solicitaron
asesoría para elaborar sus trabajos de grado, donde se
incluía el diseño
de programas en
VISUAL BASIC;
desconocido por mí, que no había pasado del TURBO y
el QUICK. Con tanto adelanto, pensé que alguien
podía haber diseñado un objeto para validar fechas
introducidas por el usuario; sin embargo, quedé
sorprendido al ver que aún no existe.
Como quiera que no poseo la más mínima idea de
cómo se elaboran los objetos insertables, se me ocurre dar
a conocer las funciones que he diseñado, con la finalidad
de que alguna otra persona elabore
un VALIDADOR DE FECHAS que, además, incluya límites
hasta meses y días, por cuanto sólo llegué a
limitar los años.
Si usted puede hacerlo, agradezco me lo haga saber, así
como el envío del objeto resultante, para mi uso personal.
Atentamente,
Gustavo Yanes
Nota: La monografía
fue escrita hace unos veinte años; la sometí a una
ligera revisión antes de enviarla sólo para
correcciones de forma. Por esta razón, los ejemplos son
los originales elaborados para cursos de
GWBASIC. Se anexó un ejemplo en VISUAL BASIC,
para demostrar el funcionamiento.
2. Introducción
La confiabilidad de los datos que se
procesan por computador es
factor importante para garantizar, a su vez, la confiabilidad de
la informacion resultante.
Muchos son los casos donde la confiabilidad depende, en gran
parte, del programa
utilizado para la recepcion de los datos a procesar;
tal como sucede con las fechas.
Una fecha confiable es aquella que se encuentra dentro de un
rango dado de validez. El programador debe, entonces, procurar
que quien introduzca los datos se encuentre limitado a un
número finito de posibilidades para cometer errores; es
decir: sólo podrá introducir una fecha errada si
está dentro del rango de validez dado.
El rango de esta validez de las fechas determinado por:
A.- Los días, meses y años deben ser números
enteros positivos.
B.- El día no puede ser mayor a 31 para los meses 1, 3, 5,
7, 8, 10, 12.
C.- El día no puede ser mayor a 30 para los meses 4, 6, 9,
11.
D.- Si el mes es 2, el día no puede ser mayor a 29, si el
año es bisiesto; ni puede ser mayor a 28, si el año
no es bisiesto.
E.- El mes no puede ser mayor a 12.
F.- El año no puede ser menor a un año dado ni
mayor a otro año dado. En todo caso la primera
condición es necesaria; el límite inferior del
rango de validez para los años será 1583 por
cuanto a finales del año 1582 se inició el
calendario actual. Si se trata, por ejemplo, de nacimientos, el
año no será mayor que el año en curso ni
inferior a 1583. Ahora bien, si se trata de nacimientos ocurridos
en este siglo, el año no puede ser menor que 1901.
La comprobacion de la validez de las fechas ha sido resuelta de
muchas maneras. Comúnmente se validan por separado las
condiciones A, E y F citadas anteriormente, además de que
el día no sea mayor a 31; luego se validan las condiciones
B, C y D.
Validar las condiciones B y C, no representan problema, ya que
once de los doce meses poseen rangos fijos de validez para los
días, cuyos limites superiores pueden ser asignados a una
tabla para realizar comprobaciones.
El problema principal radica en validar las entradas para el mes
2, ya que su limite superior varía entre 28 y 29 en
función
de que el año no sea, o sea bisiesto respectivamente. Lo
que suele resolverse haciendo un estudio especial en caso de que
el mes introducido sea 2: se determina si el año es o no
bisiesto para asignar el límite superior correspondiente a
los días y realizar la posterior comprobación.
La función
ELAINE que describo, calcula el limite superior correspon-diente
al mes introducido, incluyendo febrero para los años
bisiestos o no. Esta función se utiliza para validar las
condiciones B, C y D. Sustituye, en una sola línea de
programa, la
tabla y todas las funciones lógicas y operaciones
necesarias para determinar el límite máximo
correspondiente a febrero.
La función REINA se utiliza para validar, en particular,
las condiciones A, E, F y que el día introducido no sea
mayor que el límite superior calculado medíante la
función ELAINE. Es decir: con ella se validan todas las
condiciones A……..F, con un menor número de lí
neas de programa y funciones lógicas.
Finalmente, se incluye la función SENAY, como caso
curioso, para deter-minar si se ha introducido una fecha
correspondiente a los nueve días que fueron eliminados del
calendario en la época del Papa Gregorio.
La operatividad de las funciones arriba mencionadas Ha sido
comprobada en GWBASIC, BASICA y TURBO BASIC. Para su
utilización en otros lenguajes deberá asegurarse
que contemplen las funciones: SIGNO, VALOR
ABSOLUTO, DIVISION ENTERA y MODULO, de no ser así,
deberán hacerse los ajustes nece-sarios utilizando
expresiones equivalentes. En cualquier caso, las entradas
serán números enteros, ya que el comportamiento
para reales no enteros no se garantiza, así como para
fechas anteriores al 09.10.1582.
Division
Entera
Es el cociente entero de la división de dos
números. Por ejemplo: 45 = 0; 300200 = 1;
( ) 83 = 2; 5025 = 2.
En estos casos los residuos son 4; 100; 2 y 0 repectivamente.
Multiplo
Un número X es múltiplo de Y si su división
entera de X entre Y da como resto 0.
Se dice, entonces, que X es de la forma nY, ( X = nY ) con
n=1,2,3,4,……
Año Secular
Todo año que marca el final de
un siglo. Son seculares, por ejemplo, los años: 1600,
1800, 2000, 2500… Todo año secular es múltiplo de
100.
Año Bisiesto
Año de 366 días. En los años bisiestos,
febrero posee 29 días en vez de 28. Son bisiestos todos
los años múltiplos de 4, salvo los seculares que no
son múltiplos de 400.
Modulo
Es el residuo de la división entera efectuada ( MOD) entre
dos números; de las divisiones anteriores tendremos: 4 MOD
5 = 4; 300 MOD 200 = 100; 8 MOD 3 = 2 y 50 MOD 25 = 0.
Nótese que si X es múltiplo de Y se
tendrá que X MOD Y = 0.
Signo
La función signo( SGN ) aplicada a un número o
expresión matemática
da como resultado un número entero perteneciente al
conjunto {-1,0,1}
y está definida por:
SGN(A) = -1 si A < 0
SGN(A) = 0 si A = 0
SGN(A) = 1 si A > 0
VALOR ABSOLUTO
El valor absoluto
de un número se determina (ABS) medíante la
función definida así :
ABS(X) = X si X > 0
ABS(X) = 0 si X = 0
ABS(X) = -X si X < 0
(El valor absoluto siempre es un número positivo ó
cero.)
4. Descripción de las funciones
Por razones de longitud, las funciones podrán
aparecer escritas en más de una línea; pero,
deberá interpretarse que las mismas se
escribirán en los programas en una
sóla línea.
Función
elaine
Objetivo:
Calcular el límite superior para los días del mes
introducido, incluyendo febrero.
Sean M = mes y A = año. La función ELAINE se define
por:
ELAINE(M,A) = (30+(M+M8) MOD 2) – ((SGN(M-2)+1) MOD 2) *
((SGN(A MOD 4)+1)+((SGN(A MOD 100)+ SGN(A MOD 400)) MOD 2))
Obsérvese que ELAINE es una función compuesta
formada, a su vez, por otras funciones compuestas; para demostrar
como trabaja, la dividiremos en funcio-nes más simples y
construiremos tablas para calcular los valores
correspondientes:
Sean:
B= M+M8; C= B MOD 2; D= 30 + C (I)
E= M-2; F= SGN(E); G= F+1; H= G MOD 2 (II)
I= A MOD 4; J= SGN(I); K= J + 1 (III)
L= A MOD 100; X= SGN(L) (IV)
N= A MOD 400; O= SGN(N) (V)
P= X+O; Q= P MOD 2 (VI)
Trabajando con I y II se tiene:
I II
M M8 B C D E F G H
1 0 1 1 31 -1 -1 0 0
2 0 2 0 30 0 0 1 1
3 0 3 1 31 1 1 2 0
4 0 4 0 30 2 1 2 0
5 0 5 1 31 3 1 2 0
6 0 6 0 30 4 1 2 0
7 0 7 1 31 5 1 2 0
8 1 9 1 31 6 1 2 0
9 1 10 0 30 7 1 2 0
10 1 11 1 31 8 1 2 0
11 1 12 0 30 9 1 2 0
12 1 13 1 31 10 1 2 0
Obsérvese en I que la función compuesta D
tiene como salida los límites
superiores de los meses, excepto febrero que tiene como
límite superior 30. En II podremos observar que la salida
es 1 para febrero y 0 para el resto de los meses.
Si atendemos a la función ELAINE podemos observar que la
misma es una diferencia de funciones donde el minuendo es D y el
sustraendo es un producto, uno
de cuyos factores es H. El factor a que hemos hecho referencia
tendrá valor 0 (cero) para cualquier mes diferente
de febrero y 1 para este último, por lo que el sustraendo
será 0 para los meses diferentes de febrero y un
valor diferente de cero para el mes citado; veamos ahora como el
sustraendo toma el valor 2 para febrero en año no
bisisesto y 1 para febrero en año bisiesto (III al
VI).
Las funciones III, IV y V se utilizan para determinar si el
año introducido es múltiplo de 4, de 100 y de 400
respectivamente. Los años serán representados por
sus equivalentes en las clases módulo 4, módulo 100
y módulo 400.
Para el estudio de las funciones III representaremos al
año por las formas 4n; 4n+1; 4n+2; 4n+3. Entonces:
A I J K
4n 0 0 1
4n+1 1 1 2
4n+2 2 1 2
4n+3 3 1 2
Véase que K toma el valor 2 para los años
que no son múltiplos de 4, los cuales no son bisiestos, y
el valor 1 para los múltiplos de 4, que serán
bisiestos (a excepción de los seculares no divisibles por
400).
Para las funciones IV, haremos:
A L X
100n 0 0
100n+1 1 1
100n+2 2 1
. . .
. . .
100n+99 99 1
Es decir: X vale 0 para los años seculares y 1 para los no
seculares.
Con las funciones V hacemos:
A N O
400n 0 0
400n+1 1 1
400n+2 2 1
. . .
. . .
. . .
400n+399 399 1
Es decir: O vale cero para los años seculares divisibles
entre 400, y 1 para el resto.
Combinando las salidas de IV y V tenemos:
X O P Q Nótese que X=1 y O=0
0 0 0 0 es imposible ya que no puede ser A múlti-
0 1 1 1 plo de 400 y no serlo de 100.
1 1 2 0
La función ELAINE puede expresarse asi:
ELAINE = D – H*(K+Q)
Donde :
D Toma como valores los
límites máximos en días para cada mes, salvo
febrero en cuyo caso vale 30.
H Vale 1 para el mes 2 y 0 para el resto de los meses. Con lo que
el producto
tendrá un valor diferente de 0 sólo para
febrero.
K Vale 1 para los años divisibles por 4, y 2 para el resto
de los años.
Q Vale 1 para los años seculares no divisibles por 400, y
0 para el resto de los años.
Las posibles combinaciones de K+Q serán:
K Q K+Q
1 1 2 Obsérvese que K=2 y Q=1 no es posible,
1 0 1 pues el año sería múltiplo de 100
sin
2 0 2 serlo de 4.
Luego, K+Q vale 1 para los años múltiplos
de 4 salvo los seculares no múltiplos de 400; y toma el
valor 2, tanto para estos últimos, como para el resto de
los años.
En otras palabras, K+Q vale 1 para los años bisiestos y 2
para los no bisiestos.
Como H vale 1 para el mes 2 y 0 para el resto tendremos: H*(K+Q)
vale 1 para febrero en años bisiestos, 2 para febrero en
años no bisiestos y 0 para cualquier otro mes
independientemente del año.
Finalmente se tendrá que ELAINE = D-H*(K+Q)
valdrá :
29 para febrero en años bisiestos.
28 para febrero en años no bisiestos.
D para cualquier otro mes.
Funcion reina
Objetivo:
Producir una salida que sirva para determinar si una fecha
introducida se encuentra dentro su rango de validez, es decir: si
cumple las condiciones A…F.
Por razones de longitud, la función será
presentada en tres líneas, pero se escribirá en una
sola línea de programa. Sean D=días; M=mes;
A=año; ELAINE, el resultado de aplicar la función
mencionada; Amin, el límite inferior para los años
y Amax es el límite superior.
REINA(D,ELAINE,M,A,Amin,Amax)=(ABS(SGN(SGN(D)+SGN(ELAINE+1-D)-2))+1)
*
(ABS(SGN((SGN(M)+SGN(13-M)-2))*2)+1)*(((ABS(SGN(SGN(A-Amin+1)+SGN(Amax-A+1)-2)))
*4)+1)
Observemos que la función está compuesta por el
producto de tres factores donde el primero proporciona la
salida para validar el día, el segundo la correspondiente
para el mes y el tercero para el año.
La función posee una variante en caso de que no se desee
limitar los años superiormente; en este caso se elimina la
variable Amax de la definición. El tercer factor se
escribe
(((ABS(SGN(SGN(A-Amin+1)-1)))*4)+1)
Analicemos el primer factor, haciendo:
B=SGN(D); C=SGN(ELAINE-D+1); E=B+C; F=E-2; G=SGN(F);
H=ABS(G); I=H+1.
Luego los cálculos para el día (D)
introducido serán:
-1 Si D es un número negativo.
SGN(D)= 0 Si D es 0.
1 Si D es un número positivo.
-1 Si D supera en más de 1 días el límite
superior (ELAINE) calculado.
SGN(ELAINE+1-D) =
0 Si D supera en 1 día el límite superior (ELAINE)
calculado.
1 Si D es menor o igual al límite superior (ELAINE)
calculado.
Los valores de
B y C estarán comprendidos en el conjunto
{-1,0,1} de tal
manera que cuando B adquiera los valores -1
ó 0, C adquirirá el valor 1.
Análoga-mente, cuando C adquiera los valores -1 ó
0, B adquirirá el valor 1. El día
será válido únicamente cuando tanto B
como C adquieran el valor 1 y no lo será en
cualquier otro caso.
Hagamos la tabla:
B C E F G H I
-1 1 0 -2 -1 1 2
0 1 1 -1 -1 1 2
1 1 2 0 0 0 1
1 0 1 -1 -1 1 2
1 -1 0 -2 -1 1 2
Como el día es válido sólo cuando B
y C toman el valor 1, simultáneamente, tendremos que el
primer factor toma el valor 1 cuando el día es
válido y 2 cuando no lo es.
Consideremos el segundo factor:
(ABS(SGN((SGN(M)+SGN(13-M)-2))*2)+1)
Hagamos: A=SGN(M); B=SGN(13-M); C=A+B; D=C-2; E=SGN(D);
F=E*2; G=ABS(F); H=G+1
Luego, los cálculos para el mes introducido
serán:
-1 Si el M es un número negativo.
SGN(M)= 0 Si M es cero.
1 Si M es un número positivo.
-1 Si M es mayor que 13.
SGN(13-M)= 0 Si M es 13.
1 Si M es menor o igual a 12
Los valores de A y B estarán comprendidos en el
conjunto { -1,0,1}
de tal manera que cuando A adquiera los valores -1 ó
0, B adquirirá el valor 1. Análoga-mente,
cuando B adquiera los valores -1 ó 0, A
adquirirá el valor 1. El mes será
vá-lido únicamente cuando tanto A como B adquieran
el valor 1 y no lo será en cual-quier otro caso.
Hagamos la tabla:
A B C D E F G H
-1 1 0 -2 -1 -2 2 3
0 1 1 -1 -1 -2 2 3
1 1 2 0 0 0 0 1
1 0 1 -1 -1 -2 2 3
1 -1 0 -2 -1 -2 2 3
Como el mes es válido sólo cuando A y B
toman el valor 1 simultáneamente, tendremos que el segundo
factor toma el valor 1 cuando el mes es válido y 3 cuando
no lo es.
Consideremos el tercer factor:
(((ABS(SGN(SGN(A-Amin+1)+SGN(Amax-A+1)-2)))*4)+1)
Haciendo:
B=SGN(A-Amin+1); C=SGN(Amax-A+1); E=B+C; F=E-2; G=SGN(F);
H=ABS(G); I=H*4; J=I+1.
Y su variante
(((ABS(SGN(SGN(A-Amin+1)-1)))*4)+1); con: F=C-1
Haciendo los cálculos previos para el año A
tenemos:
-1 Si A es menor que Amin en más de dos años.
SGN(A-Amin+1)= 0 Si A es un año menor que Amin.
1 Si A es mayor o igual a Amin.
-1 Si A excede a Amax en más de un año.
SGN(Amax-A+1)= 0 Si A excede a Amax en un año.
1 Si A es menor o igual a Amax.
Los valores de B y C estarán comprendidos en el
conjunto { -1,0,1}
de tal manera que cuando B adquiera los valores -1 ó
0, C adquirirá el valor 1. Análogamente, cuando C
adquiera los valores -1 ó 0, B tomará el
valor 1. El año será válido
únicamente cuando tanto B como C adquieran el valor 1 y no
lo será en cualquier otro caso. Si trabajamos con la
variante tendremos que el año será
válido siempre que B sea 1.
Hagamos las tablas:
(Forma general)
B C E F G H I J
-1 1 0 -2 -1 1 4 5
0 1 1 -1 -1 1 4 5
1 1 2 0 0 0 0 1
1 0 1 -1 -1 1 4 5
1 -1 0 2 -1 1 4 5
(Variante)
B F G H I J
-1 -2 -1 1 4 5
0 -1 -1 1 4 5
1 0 0 0 0 1
Como el año es válido sólo cuando B
y C toman el valor 1 simultánea-mente ( o B=1 en el caso
de la variante), tendremos que el tercer factor toma el valor 1
cuando el año es válido y 5 cuando no lo es.
Construyamos ahora una tabla para el producto de los tres
factores expresando la función REINA así
REINA(I,H,J)=I*H*J (H, I, J, son las salidas)
I H J REINA VÁLIDA FALLAN
1 1 1 1 SI NINGUNO
1 3 1 3 NO MES
1 1 5 5 NO AÑO
1 3 5 15 NO MES Y AÑO
2 1 1 2 NO DÍA
2 3 1 6 NO DÍA Y MES
2 1 5 10 NO DÍA Y AÑO
2 3 5 30 NO DÍA, MES Y AÑO
Como puede observarse, la fecha es válida, si y
sólo si REINA=1. Con esto basta para validar la entrada.
Ahora bien: ¿Para quë sirven los otros valores de la
función REINA ?: ellos sirven para desplegar los mensajes,
utilizando la función MOD.
De la tabla anterior se infiere que:
Si falla REINA MOD 2 REINA MOD 3 REINA MOD 5
Sólo el día 0 2 2
Sólo el mes 1 0 3
Sólo el año 1 2 0
Día y mes 0 0 1
Días y año 0 1 0
Mes y año 1 0 0
Día, mes y año 0 0 0
Todos los mensajes correspondientes se pueden desplegar
con las siguien-tes tres instrucciones:
Si REINA MOD 2 = 0 desplegar el mensaje "ERROR EN EL
DÍA"
Si REINA MOD 3 = 0 desplegar el mensaje "ERROR EN EL MES"
Si REINA MOD 5 = 0 deplegar el mensaje "ERROR EN EL
AÑO"
A continuación se presenta un ejemplo de rutina para
validar fechas. En ella no se considera un año
máximo y, como año mínimo, se ha considerado
1990.
10 CLS
20 DEF FNELAINE(X,Y) =(30+(X+X8) MOD 2)-((SGN(X-2)+1)MOD 2)*
((SGN(Y MOD 4)+1)+((SGN( Y MOD 100)+SGN(Y MOD 400)) MOD 2))
30 DEF FNREINA(O,P,Q,R,T)= (ABS(SGN(SGN(O)+SGN(P+1-D)-2))+1)*
(ABS(SGN((SGN(Q)+SGN(13-Q)-2))*2)+1)*(((ABS(SGN(R-T+1)-1)))
*4)+1)
40 LOCATE 8,10:INPUT "DÍA ",D
50 LOCATE 10,10:INPUT "MES ",M
60 LOCATE 12,10:INPUT "AÑO ",A
70 ELAINE=FNELAINE(M,A)
80 REINA=FNREINA(D,ELAINE,M,A,1990)
90 LOCATE 18,10
100 IF REINA MOD 2= 0 THEN PRINT "ERROR EN EL DÍA -";
110 IF REINA MOD 3= 0 THEN PRINT "ERROR EN EL MES -";
120 IF REINA MOD 5= 0 THEN PRINT "ERROR EN EL AÑO "
130 END
Funcion Senay
OBJETIVO: Detectar fechas inexistentes en el calen-dario
Gregoriano, si el límite mínimo para los
años es menor a 1583.
Si por alguna razón el límite inferior para los
años es menor que 1583, la función SENAY
resultará útil para detectar aquellas fechas
que coincidan con algunas de las que fueron eliminadas del
calendario de 1582.
Es de hacer notar que para 1582 el calendario civil utilizado por
el mundo occidental era el Juliano ( impuesto por
Julio César) compuesto por años de 365 días
y cada cuatro años uno de 366 días. Sin embargo
persistía un error con respecto al calendario solar que
acumuló unos nueve días de retraso desde la
época de Julio César hasta el año 1582. El
Papa Gregorio eliminó la causa del error disponiendo que
los años seculares serían bisiestos sólo si
son divisibles entre 400 y eliminó el error acumulado
haciendo que al día 5 de octubre de 1582 le siguiera
inmedíatamente el día 15 de octubre. Es decir: el
período 6-10 al 14-10-1582 no existió.
Con la función SENAY se detecta si se ha introducido una
fecha del período inexistente.
SENAY(D,M,A)=6*(1-(SGN(ABS(SGN(5-D)+SGN(15-D))+
ABS(M-10)+ABS(A-1582))))
Para demostrar como funciona hagamos:
P=SGN(5-D)
Q=SGN(15-D)
R=ABS(P+Q)
S=ABS(M-10)
T=ABS(A-1582)
Luego:
P Q P+Q R
D<5 1 1 2 2
D=5 0 1 1 1
D>5 y D<15 -1 1 0 0
D=15 -1 0 -1 1
D>15 -1 -1 -2 2
Obsérvese que:
R=0 solamente cuando el día está comprendido entre
6 y 14. En cualquier otro caso será R>0.
S=0 solamente cuando el mes es 10. En Los otros casos será
S>0.
T=0 solamente cuando el año es 1582. En cualquier otro
caso será T>0.
Luego: SGN(R+S+T)=0 cuando la fecha coincide con alguna de las
elimi-nadas del calendario. De resto, será siempre
1.
Y en consecuencia 6 * (1-SGN(R+S+T)) = 6 siempre que la fecha
intro-ducida coincida con alguna de las eliminadas del
calendario. De lo contrario la expresión anterior
tendrá el valor 0.
Si a la función REINA se le suma la función SENAY,
su valor se incre-mentará en el de esta
última; por lo tanto, si la fecha introducida coincide con
alguna de las eliminadas del calendario, REINA
tomará el valor 7 y, en cualquier otro caso,
conservará el valor originalmente calculado. Esto nos
permite introducir una nueva condición y mensaje:
Si REINA MOD 7 = 0 desplegar el mensaje
"ERROR LA FECHA NUNCA EXISTIO".
Nuestro programa de ejemplo, considerando como límites
mínimo y máximo a los años 1500 y 1995,
quedaría así :
10 CLS
20 DEF FNELAINE(X,Y)=(30+(X+X8) MOD 2)- ((SGN(X-2)+1)MOD 2)*
((SGN(Y MOD 4)+1)+((SGN(Y MOD 100)+SGN(Y MOD 400)) MOD 2))
30 DEF FNSENAY(D,M,A)=6*(1-(SGN(ABS(SGN(5-D)+SGN(15-D))
+ABS(M-10)+ABS(A-1582))))
35 DEF FNREINA(O,P,Q,R,S,T)=(ABS(SGN(SGN(O)+SGN(P+1-D)-2))+1)
(ABS(SGN((SGN(Q)+SGN(13-Q)-2))*2)+1)*(((ABS(SGN(SGN(R-T+1)
+SGN(S-R+1)-2)))*4)+1)
40 LOCATE 8,10:INPUT "DÍA ",D
50 LOCATE 10,10:INPUT "MES ",M
60 LOCATE 12,10:INPUT "AÑO ",A
70 ELAINE =FNELAINE(M,A)
75 SENAY =FNSENAY(D,M,A)
80 REINA =FNREINA(D,ELAINE,M,A,1995,1500) +SENAY
100 IF REINA MOD 2= 0 THEN PRINT "ERROR EN EL DÍA -";
110 IF REINA MOD 3= 0 THEN PRINT "ERROR EN EL MES -";
120 IF REINA MOD 5= 0 THEN PRINT "ERROR EN EL AÑO "
125 IF REINA MOD 7= 0 THEN PRINT "ERROR LA FECHA NUNCA
EXISTIO"
130 END
Las funciones descritas facilitan la validación
de fechas, en aquellos lenguajes de
programación carentes de funciones internas que
realicen tal actividad.
Las dos primeras (ELAINE y REINA), son básicas en
cualquier programa que solicite entrada de fechas. Los
años límite pueden ser cargados a través de
un archivo de
configuración que sería leído al arrancar el
programa, facilitando así la actualización de los
mismos en el momento requerido sin tener que alterar el programa
fuente; a la vez que evitaría la inoperatividad de los
programas ejecutables (.EXE), como el consecuente desagrado de
los usuarios.
Espero haber realizado un aporte, sobre todo, a los programadores
y estudíantes del lenguaje
BASIC; por cuanto el mismo carece de este tipo de fun-ciones
internas y, además, por ser el lenguaje
utilizado en la mayoría de los centros educativos como
lenguaje
introductorio, para el aprendizaje de
la computación.
Demostración
en visual basi
Si tienes VISUAL BASIC,
prepara una forma como la anterior y copia el programa que se
encuentra más abajo. Verás que Visual cambia el
formato cuando la fecha está errada; pero acepta el error.
Si se introduce uno de los días perdidos en 1582, Visual
ni se entera.
Agrega un botón para salir
Dim díasmaximo, dmax, díaperdido As Integer
Dim titulo As String
Function elaine(mes As Integer, año As Integer)
elaine = (30 + (mes + mes 8) Mod 2) – ((Sgn(mes – 2) + 1) Mod
2) * ((Sgn(año Mod 4) + 1) + ((Sgn(año Mod 100) +
Sgn(año
Mod 400)) Mod 2))
End Function
Function Reina(día As Integer, limax As Integer, mes As
Integer, año As Integer, amin As Integer, amax As
Integer)
Reina = (Abs(Sgn(Sgn(día) + Sgn(limax + 1 – día) –
2)) + 1) * (Abs(Sgn((Sgn(mes) + Sgn(13 – mes) – 2)) * 2) + 1) *
(((Abs(Sgn(Sgn(año – amin + 1) + Sgn(amax – año +
1) – 2))) * 4) + 1)
End Function
Function Senay(día As Integer, mes As Integer, año
As Integer)
Senay = 6 * (1 – (Sgn(Abs(Sgn(5 – día) + Sgn(15 –
día)) + Abs(mes – 10) + Abs(año – 1582))))
End Function
Private Sub Command1_Click()
mifecha = Text1.Text & " " & Text2.Text & " " &
Text3.Text
Text4.Text = Format(mifecha, "dddd d mm yyyy")
díasmáximo = elaine(Text2.Text, Text3.Text)
dmax = díasmáximo
fechabuena = Reina(Text1.Text, dmax, Text2.Text, Text3.Text,
1582, 9000)
díaperdido = Senay(Text1.Text, Text2.Text, Text3.Text)
fechabuena = fechabuena + díaperdido
titulo = "MENSAJE PROGRAMADO "
If fechabuena = 1 Then msg = "Fecha válida":
Label3.Caption = "Fecha válida"
If fechabuena Mod 2 = 0 Then msg = "Error en el día"
If fechabuena Mod 3 = 0 Then msg = msg & vbCr & "Error en
el mes"
If fechabuena Mod 5 = 0 Then msg = msg & vbCr & "Error en
el año"
MsgBox msg, vbInformation, titulo
Label3.Caption = "Vuelve a cambiar"
End Sub
Private Sub Command2_Click()
Unload Me
End Sub
Autor:
Gustavo Yanes Yanes