🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Now, Date y Time en Excel — leer el reloj, y por qué Date también es una instrucción

|

VBA Now, Date y Time en Excel — leer el reloj, y por qué Date también es una instrucción

TL;DRNow devuelve la fecha y la hora, Date devuelve hoy a medianoche, y Time devuelve solo la hora del día. Por debajo, todos son un mismo número: una fecha de VBA es un Double donde la parte entera es el día y la fracción es la hora. Por eso If stamp = Date casi nunca coincide con un valor que vino de NowNow arrastra una fracción, Date no. Quita la hora con Int(Now) o DateValue(Now) antes de comparar.

Sub ClockDemo()
    Debug.Print Now          ' 2026-08-26 14:30:07  - fecha + hora
    Debug.Print Date         ' 2026-08-26           - hoy a medianoche
    Debug.Print Time         ' 14:30:07             - solo la hora
    Debug.Print Int(Now)     ' 2026-08-26           - Now sin la hora = Date
End Sub

Una fecha de VBA no es un tipo especial en cuyo interior no puedes mirar — es un simple Double con una máscara puesta. La parte entera cuenta los días desde el 30 de diciembre de 1899; la parte decimal es la hora del día (0,5 = mediodía). Now, Date y Time son solo tres maneras de leer el mismo reloj y volcarlo en ese número. En cuanto ves el Double, cada bug de comparación de fechas de tus macros resulta ser la misma historia: una fracción despistada donde no esperabas ninguna.

Lo que aprenderás

  • El modelo mental — una fecha es un Double: entero = día, fracción = hora
  • Por qué Now, Date y Time devuelven números distintos del mismo reloj
  • Por qué If stamp = Date nunca coincide con un valor de Now — y cómo arreglarlo
  • Que Date y Time también son instrucciones que reajustan el reloj del sistema
  • Por qué Now es hora local, no UTC, en un libro compartido
  • Cómo formatear una marca de tiempo para mostrarla sin romper el número que hay debajo

El modelo mental: una fecha es un Double

La única idea que hace que todo encaje: un valor Date de VBA es un número. Asigna Now a un Double y VBA te enseña la maquinaria:

Dim d As Double
d = Now                       ' p.ej. 46261.6042
' 46261     -> dias desde 1899-12-30  -> la fecha
' 0.6042    -> fraccion de un dia     -> ~14:30 la hora

La parte entera es el número de serie del día; la parte decimal es la hora como fracción de 24 horas. 0,25 son las 6 de la mañana, 0,5 el mediodía, 0,75 las 6 de la tarde. Todo lo demás se deduce de aquí. Sumar 1 te mueve un día; sumar 1/24 te mueve una hora. Las tres funciones de reloj se diferencian solo en qué parte del número rellenan:

  • Now rellena ambas partes — el día entero y la hora decimal.
  • Date rellena solo el entero — hoy, con la fracción forzada a 0 (medianoche).
  • Time rellena solo la fracción — la hora del día, con la parte entera a 0.

Ese es el modelo completo. El resto de esta guía es lo que ocurre cuando olvidas qué parte está rellena.

Now vs Date vs Time: tres lecturas de un mismo reloj

Echa mano de la que corresponda a la pregunta que de verdad te estás haciendo:

  • Now — una marca de tiempo completa, fecha y hora. Úsala para registrar cuándo ocurrió algo (ws.Range("A1") = Now).
  • Date — la fecha de hoy del calendario a medianoche. Úsala para la lógica de qué día — si esta factura está vencida, si hoy es fin de semana — donde la hora del día es ruido.
  • Time — la hora del día sin fecha. Úsala para sellar una hora o medir un instante de reloj dentro de un día.
Range("A1") = Now      ' 2026-08-26 14:30:07  - registra un evento
Range("A2") = Date     ' 2026-08-26           - una columna de vencimiento
Range("A3") = Time     ' 14:30:07             - hora de inicio de turno

Now = Date + Time es cierto hasta el segundo, porque así es literalmente como se construye el número: Date aporta el entero, Time aporta la fracción.

Por qué If stamp = Date nunca coincide con un valor de Now

Este es el bug estrella, y se deriva directamente del Double. Guardas una marca de tiempo con Now y más tarde compruebas si ocurrió hoy:

saved = Now                       ' 46261.6042  (tiene fraccion de hora)
' ...mas tarde...
If saved = Date Then MsgBox "today"   ' Date es 46261.0000 - NUNCA igual

Date es un número entero; saved arrastra una fracción. 46261,6042 = 46261,0 es False, así que la rama nunca se dispara en silencio — sin error, solo lógica que calladamente no hace nada. El arreglo es comparar lo comparable quitando la hora antes de la prueba:

If Int(saved) = Date Then MsgBox "today"        ' Int elimina la fraccion
If DateValue(saved) = Date Then MsgBox "today"  ' DateValue hace lo mismo, a proposito

Int(d) trunca la fracción y deja la fecha pura. DateValue hace lo mismo pero se lee como «la parte de fecha de este valor», que le queda más claro a quien venga después. La regla para llevarse a casa: nunca compares un valor derivado de Now con = a menos que ambos lados estén normalizados a la misma precisión. El bug de fechas del tipo «funcionaba en las pruebas» es siempre una fracción despistada.

Date y Time también son instrucciones que ajustan el reloj

Aquí está la trampa que sorprende a todo el mundo una vez: Date y Time no son solo funciones que leen el reloj — también son instrucciones que lo escriben. Con una asignación a la izquierda, cambian el reloj del sistema del equipo:

x = Date              ' FUNCION - lee hoy en x
Date = #2030-01-01#   ' INSTRUCCION - fija la fecha de TODO EL EQUIPO a 2030
Time = #08:00:00#     ' INSTRUCCION - fija la hora del sistema

La misma palabra, efecto opuesto, decidido por completo según esté a la izquierda de un = o no. Ajustar el reloj del sistema afecta a todas las aplicaciones de la máquina, requiere permisos de administrador y casi nunca es lo que una macro de hoja de cálculo debería hacer — un Date = algo despistado es una errata de verdad peligrosa. Lee el reloj, nunca lo ajustes: mantén Date y Time en el lado derecho de tus asignaciones.

Now es hora local, no UTC

Now lee el reloj local de la máquina — su valor depende de la zona horaria del usuario y del ajuste de horario de verano. En un libro compartido entre regiones, dos personas que pulsan el mismo botón sellan dos horas distintas, y ninguna es UTC. VBA no tiene función UTC integrada; obtener la hora universal requiere una llamada a la API de Windows (GetSystemTime) o un ayudante:

' Now = hora local del reloj - bien para una sola maquina,
' ambigua en cuanto el archivo cruza una zona horaria.
Range("Log") = Now

Para el libro de un solo usuario esto es exactamente correcto y simple. Para un registro que leerán varias regiones, o bien guardas UTC (vía la API) o bien anotas la zona horaria junto a la marca — de lo contrario una entrada de «10:00» no significa nada sin saber de quién eran esas 10:00.

Mostrar una marca de tiempo sin romper el número

Para mostrar una fecha como tú quieres, usa Format — pero recuerda que devuelve texto, no una fecha, así que es solo para visualización:

MsgBox Format(Now, "yyyy-mm-dd hh:nn:ss")   ' una String para un mensaje
cell.Value = Now                            ' guarda el Double real...
cell.NumberFormat = "yyyy-mm-dd"            ' ...y formatea la CELDA, no el valor

Escribir cell.Value = Format(Now, ...) mete en la celda una cadena que parece una fecha, y entonces SUM, la ordenación y los filtros de fecha se rompen porque la celda es texto. El hábito correcto: guarda el valor Now real y controla su aspecto con NumberFormat. Para ir en sentido contrario — convertir texto tecleado por el usuario en una fecha — usa CDate o DateSerial.

El veredicto honesto: sabe qué parte del número tienes en la mano

Now, Date y Time son triviales de llamar y fáciles de usar mal, porque el mal uso nunca lanza un error — simplemente compara en silencio los números equivocados. Cuatro reglas cubren toda la superficie:

  • Ve el Double → el entero es el día, la fracción es la hora. Now tiene ambos; Date solo el entero; Time solo la fracción.
  • Normaliza antes de compararInt(stamp) = Date, nunca stamp = Date. El bug de igualdad es siempre una fracción sobrante.
  • Lee, nunca ajustes → mantén Date/Time a la derecha del =. A la izquierda reajustan el reloj del sistema.
  • Guarda el valor, formatea la celda → conserva el Now real; usa NumberFormat o Format para su aspecto, o SUM y la ordenación se rompen.

Acierta con el modelo mental del Double y los dos grandes esfuerzos — hacer aritmética con fechas y extraer sus partes — dejan de ser un misterio también.

Cómo ayuda ExcelMaster

Los bugs de fechas que cuestan tiempo de verdad son los silenciosos: una comprobación = Date que nunca se dispara, una celda que se ordena mal porque una macro guardó Format(Now, …) como texto, un registro compartido cuyas horas significan cosas distintas para cada lector. Cada uno nace de perder la pista de qué parte del número tienes en la mano.

ExcelMaster escribe la lógica de marcas de tiempo que compara bien y guarda bien. Describe el trabajo — «registra cada ejecución con fecha y hora» o «marca las filas con fecha anterior a hoy» — y produce la llamada correcta (Now vs Date), normaliza la comparación con Int/DateValue, y mantiene el valor guardado como fecha real con el formato en la celda. Tú describes el momento que quieres capturar; él escribe el código que lo captura sin la trampa de la fracción despistada.

Preguntas frecuentes

¿Cuál es la diferencia entre Now y Date en VBA?

Now devuelve la fecha y la hora actuales; Date devuelve la fecha de hoy a medianoche (sin parte de hora). Por dentro, una fecha de VBA es un Double donde el entero es el día y la fracción es la hora — Now rellena ambos, Date solo el entero. Por eso Now y Date casi nunca son iguales aun en el mismo día, así que usa Date (o Int(Now)) siempre que la hora del día no deba importar.

¿Por qué mi comparación de fechas con = nunca funciona en VBA?

Porque un lado arrastra una fracción de hora y el otro no. Un valor de Now se ve como 46261,6042, mientras que Date es 46261,0, así que Now = Date es False. Quita la hora antes de comparar: If Int(stamp) = Date Then … o If DateValue(stamp) = Date Then …. Compara dos fechas con = solo cuando ambas se han normalizado a la misma precisión.

¿Cómo obtengo solo la hora actual en VBA?

Usa la función Time: t = Time devuelve la hora del día sin fecha (la parte entera del número es cero). Si tienes una marca de tiempo completa de Now y solo quieres su parte de hora, resta la parte de fecha: t = Now - Int(Now), que deja la fracción. Para mostrarla como texto usa Format(Time, "hh:nn:ss").

¿Now devuelve la hora UTC en VBA?

No. Now devuelve la hora local del reloj de la máquina, incluido su desfase de zona horaria y de horario de verano. VBA no tiene función UTC integrada; para la hora universal necesitas una llamada a la API de Windows como GetSystemTime. En un libro compartido entre regiones, guarda UTC o anota la zona horaria junto a la marca, o una hora registrada será ambigua.

¿Puede VBA cambiar la fecha y la hora del sistema?

Sí, y por eso es peligroso. Date y Time también son instrucciones: Date = #2030-01-01# fija la fecha del sistema del equipo y Time = #08:00:00# ajusta su reloj, afectando a todas las aplicaciones y normalmente requiriendo permisos de administrador. Mantén Date y Time en el lado derecho de una asignación para que siempre leas el reloj y nunca lo ajustes.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 26/08/2026.

Guías relacionadas: VBA DateAdd y DateDiff · VBA Weekday y DatePart · VBA Format · VBA CStr, CDate y Val · VBA Timer