TL;DR —
Nowdevuelve la fecha y la hora,Datedevuelve hoy a medianoche, yTimedevuelve solo la hora del día. Por debajo, todos son un mismo número: una fecha de VBA es unDoubledonde la parte entera es el día y la fracción es la hora. Por esoIf stamp = Datecasi nunca coincide con un valor que vino deNow—Nowarrastra una fracción,Dateno. Quita la hora conInt(Now)oDateValue(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,DateyTimedevuelven números distintos del mismo reloj - Por qué
If stamp = Datenunca coincide con un valor deNow— y cómo arreglarlo - Que
DateyTimetambién son instrucciones que reajustan el reloj del sistema - Por qué
Nowes 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:
Nowrellena ambas partes — el día entero y la hora decimal.Daterellena solo el entero — hoy, con la fracción forzada a0(medianoche).Timerellena solo la fracción — la hora del día, con la parte entera a0.
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.Nowtiene ambos;Datesolo el entero;Timesolo la fracción. - Normaliza antes de comparar →
Int(stamp) = Date, nuncastamp = Date. El bug de igualdad es siempre una fracción sobrante. - Lee, nunca ajustes → mantén
Date/Timea la derecha del=. A la izquierda reajustan el reloj del sistema. - Guarda el valor, formatea la celda → conserva el
Nowreal; usaNumberFormatoFormatpara su aspecto, oSUMy 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
