| Artículo | Visual Basic en la Crisis Informática del 2000 |
| Autor / Fuente | Harvey Triana / Referencia: Class Solutions LTD, What is the Year 2000 Problem and How Does It Affect VB? |
| Tema | Programación general |
| Creado | Noviembre 25 de 1997 |
Visual Basic en la Crísis Informática del 2000
Visión del código Visual Basic en la Crisis Informática del 2000
La tan mencionada crisis del 2000 es y seguirá siendo el tema de moda en los próximos años. Se ha escrito tanta literatura sobre esto, que podría resultar algo trivial escribir un articulo más sobre el tema. No obstante, de toda la literatura que he consultado, solo he encontrado un articulo especifico sobre las repercusiones puntuales sobre soluciones escritas en Visual Basic.

Visual Basic -hoy- procesa la centuria de datos de fecha almacenados en dos dígitos con ciertas limitaciones necesarias. VB (32 Bits) emplea una técnica llamada Windowing, un algoritmo interno que procesa correctamente un rango de fechas de 1899 a 2030 para años en dos dígitos. Es decir, para VB (32 Bits) la fecha 21/11/00 es Noviembre 21 del 2000, mientras 21/11/31 es Noviembre 21 de 1931. No ocurre lo mismo con VB (16 Bits) que para el primer caso es 1900. Veamos los siguientes ejercicios **:
Const fechaMax1 = #1/1/01#, fechaMax2 = #1/1/98#
Vera como VB (32 Bits) pasa la primera constante al año 2001, es decir, inmediatamente el editor mostrará:
Const fechaMax1 = #1/1/2001#, fechaMax2 = #1/1/98#
Pruebe estas líneas:
MsgBox Year("31/12/00")
MsgBox Year("31/12/31")
MsgBox Year("31/12/2031")
La ultima expresión es lo que esperábamos, año 2031, mientras que la anterior tiene un siglo de diferencia, año 1931. Preocuparse por Treinta años puede resultar ridículo hoy, aunque posiblemente así pensaron en los 60's y 70's. ¿Para entonces hablaran de la crisis del 2030?.
Si usted aun programa soluciones para 16 Bits, realmente debiera prestarle seria atención al asunto. La constante fechaMax1 = #1/1/01#, VB3 y VB4 (16 Bits), asume Enero 1 de 1901, a diferencia de VB (32 Bits), que entiende que se trata de Enero 1 del 2001.
Así pues, el VB actual parece no tener serios problemas. Sin embargo, los analistas colocan un alto en el camino, y es la procedencia de los datos. Como sabrá, VB puede usar diferentes fuentes de bases de datos (virtualmente todos a través de controladores ODBC). En este caso, debería filtrar los datos tipo fecha de fuentes que solo almacenan el año en dos dígitos. Por ejemplo, una estrategia es convertir las fechas almacenadas en sartas a variables Date o Variant con una asignación simple o explícitamente con CDate. No obstante, en ciertos casos debería implementar un filtro como se demuestra en el siguiente ejercicio.
Veamos, se investiga si Enero 1 del 2000 es mayor que ahora, por supuesto, esperamos que la salida sea -ok:
Dim x As String x = "1/1/00" If CDate(x) > Now Then MsgBox "ok" Else MsgBox "...?" End If
Para hacer claro el ejemplo se asigno explícitamente x = "1/1/00", pero asuma que el valor de x proviene de una base de datos antigua o de un TextBox que Usted programó para que los usuarios ingresen una fecha y lo limito a una máscara de dd/mm/yy La salida en VB (32 Bits) es "ok", mientras que VB (16 Bits) es "...?". La pregunta inmediata es ¿cómo resolver esto para VB (16 Bits)?. La respuesta es filtrar el dato para que tengamos x = "1/1/2000" y no x = "1/1/00". Cualquier programador puede solucionar esto. La siguiente función agrega la centuria al formato dd/mm/yy y la convierte a dd/mm/yyyy **:
'------------------------------------------------------------
' Agrega la centuria a una sarta-fecha del formato dd/mm/yy
' y la convierte a dd/mm/yyyy.
' HT©
'------------------------------------------------------------
Function yyyy(x As String) As String
Const MaxFrom2000 = 30
Dim rtn As String
If IsDate(CVar(x)) Then
If Mid(x, Len(x) - 2, 1) = "/" Then
rtn = Right(x, 2)
If Val(rtn) >= 0 And Val(rtn) <= MaxFrom2000 Then
rtn = Left(x, Len(x) - 2) + "20" + rtn
Else
rtn = Left(x, Len(x) - 2) + "19" + rtn
End If
Else
rtn = x
End If
End If
yyyy = rtn
End Function
Así, corregimos colocando la sarta x = yyyy("1/1/00"). Nótese que asigné una constante para el rango 2000 a 2030, esto es necesario para permitir el rango 1931 a 1999. Así se esclarece el porque del rango. Puede cambiar el valor de la constante según el análisis de sus datos y alcance de la aplicación. Recuerde que esto sólo es necesario en VB (16 bits).
También resulta muy practico, escribir una función tipo CDate, pero que adicionalmente filtre el siglo. En este caso no necesita modificar la interfaz de una aplicación que usa mascaras para almacenar la centuria en dos dígitos. Para empezar a solucionar el problema podría reemplazar todos los CDate que existan por FilterCDate. La función podría ser **:
'------------------------------------------------------------
' Filtra una sarta-fecha del formato dd/mm/yy para soportar
' la centuria 2000 dentro de un rango. Formato dd/mm/yy
' HT©
'------------------------------------------------------------
Function FilterCDate(s As String) As Variant
Const MaxFrom2000 = 30
Dim x As Variant
x = CVar(s)
If IsDate(x) Then
If Year(x) >= 1900 And Year(x) <= (1900 + MaxFrom2000) Then
x = DateSerial(100 + Year(x), Month(x), Day(x))
End If
End If
FilterCDate = x
End Function
También se podría asignar a una variable Date o Variant la expresión yyyy(miFecha$), usando la función anterior, ó, modificar yyyy para que entregue el tipo fecha directamente (es la mejor opción en cuanto a rendimiento porque no se usan las funciones Year, DateSeria, Month y Day).
El problema evidente es cuando se trata de programas grandes con interminable número de líneas y bastantes análisis e interpretación de datos empleando fechas. En este caso debería recurrir a los especialistas. Empresas como Class Solutions LTD, resuelven estos problemas a través de herramientas de software (para más información, Mark Mayes - MarkMayes@Class-Solutions.Com).
Es conveniente algo de teoría para comprender mejor la perspectiva de VB. Las variables tipo Date se almacenan como números IEEE de signo flotante de 64 bits (8 bytes), es decir de tipo Double, y van del 1 de Enero del 100 al 31 de Diciembre de 9999 (horarios de 0:00:00 a 23:59:59). Cualquier valor reconocible de fecha literal se puede asignar a las variables tipo Date. Date presentan fechas de acuerdo al formato de fecha corto reconocido por el sistema. El tipo Date indica el número de dias pasados desde Diciembre 31 de 1899.
Cuando se convierten a tipo Date otros tipos de datos numéricos, los valores a la izquierda del signo decimal representan la información de fecha, mientras que los valores a la derecha del signo decimal representan la hora. Medianoche es 0 y mediodía es 0,5. Los números enteros negativos representan fechas anteriores al 30 de diciembre de 1899.
Cuidado con la función DateSerial(año, mes, día), para el argumento año, los valores entre 0 y 29, inclusive, se interpretan como los años 2000-2029. Los valores entre 30 y 99, inclusive, se interpretan como los años 1930-1999. Para todos los demás argumentos año, utilice un año de cuatro dígitos (por ejemplo, 1800).
NOTA. VB (32 Bits) proporciona una función CVDate para asegurar la compatibilidad con versiones previas de VB. Sin embargo, puesto que no existe un tipo Date intrínseco, ya no es necesaria CVDate. La sintaxis de la función CVDate es idéntica a la de la función CDate. La diferencia está en que ésta devuelve una Variant cuyo subtipo es Date en lugar de un tipo real Date. Se puede lograr el mismo efecto convirtiendo una expresión a una Date y asignándola después a una Variant. Esta técnica es coherente con la conversión de todos los demás tipos intrínsecos a sus subtipos Variant equivalentes.
Si usted usa formatos de cuatro dígitos para capturar en año, no tendrá problemas con el 2000. No obstante, si captura el año desde dos dígitos (desde una base de datos antigua o desde una mascara de su aplicación), debe tener precauciones procesando fechas fuera del rango 1930-2029. Si diseña soluciones para 16 bits con VB, debería implementar una estrategia para que sus aplicaciones no se hundan en el bug del milenio.
Visual Basic de 16 bits en conversión implícita utiliza una ventana lógica de operación correcta de 1900 a 1999. Visual Basic en 32 bits utiliza funciones del Sistema Operativo (Win32) para una ventana 1930-2029. Para herramientas de Visual Basic se puede visitar la siguiente dirección electrónica: www.class-solutions.com
Aquí presento unas líneas JavaScript de mí estimado colega Guillermo Som (http://wcostasol.es/guille/) con alguna pequeña modificación:
** NOTA. Todos los ejemplos suponen que el sistema trabaja bajo el formato de fecha con orden Día/Mes/Año, en otro caso verifíque la configuración del sistema y haga los cambios pertinentes en los ejemplos y código. El separador también se asume como la barra divisoria o slash, "/".
Harvey Triana
Derechos Reservados. Autorización solo para programación