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.


¿Deberíamos Preocuparnos los Programadores 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).


El Tipo Date

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.


Conclusiones

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.


Nota de Microsoft

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


¿Cuánto Falta para el 2000?

Aquí presento unas líneas JavaScript de mí estimado colega Guillermo Som (http://wcostasol.es/guille/) con alguna pequeña modificación:


Fecha Actual
Días para el 1/Ene/2000
Horas para el 1/Ene/2000
Minutos para el 1/Ene/2000
Segundos para el 1/Ene/2000

** 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