TL;DR —
Nowrenvoie la date et l'heure,Daterenvoie aujourd'hui à minuit, etTimene renvoie que l'heure du jour. Dessous, ce n'est qu'un seul nombre : une date VBA est unDoubleoù la partie entière est le jour et la partie décimale est l'heure. Voilà pourquoiIf stamp = Datene correspond presque jamais à une valeur issue deNow—Nowporte une fraction,Datenon. Retirez l'heure avecInt(Now)ouDateValue(Now)avant de comparer.
Sub ClockDemo()
Debug.Print Now ' 2026-08-26 14:30:07 - date + heure
Debug.Print Date ' 2026-08-26 - aujourd'hui a minuit
Debug.Print Time ' 14:30:07 - heure seule
Debug.Print Int(Now) ' 2026-08-26 - Now sans l'heure = Date
End Sub
Une date VBA n'est pas un type opaque dans lequel vous ne pouvez pas regarder — c'est un simple Double
qui porte un masque. La partie entière compte les jours depuis le 30 décembre 1899 ; la partie
décimale est l'heure du jour (0,5 = midi). Now, Date et Time ne sont que trois façons de lire
cette même horloge dans ce nombre. Une fois que vous voyez le Double, chaque bug de comparaison de dates
dans vos macros se révèle être la même histoire : une fraction parasite là où vous ne l'attendiez pas.
Ce que vous allez apprendre
- Le modèle mental — une date est un
Double: entier = jour, fraction = heure - Pourquoi
Now,DateetTimerenvoient des nombres différents de la même horloge - Pourquoi
If stamp = Datene correspond jamais en silence à une valeurNow— et comment y remédier - Que
DateetTimesont aussi des instructions qui réinitialisent l'horloge système - Pourquoi
Nowdonne l'heure locale, pas UTC, dans un classeur partagé - Comment formater un horodatage pour l'affichage sans casser le nombre qui est dessous
Le modèle mental : une date est un Double
L'idée unique qui fait tout déclencher : une valeur Date VBA est un nombre. Affectez Now à un
Double et VBA vous montre la mécanique :
Dim d As Double
d = Now ' ex. 46261.6042
' 46261 -> jours depuis le 1899-12-30 -> la date
' 0.6042 -> fraction de jour -> ~14:30 l'heure
La partie entière est le numéro de série du jour ; la partie décimale est l'heure exprimée en
fraction de 24 heures. 0,25 c'est 6 h, 0,5 c'est midi, 0,75 c'est 18 h. Tout le reste en découle.
Ajouter 1 vous fait avancer d'un jour ; ajouter 1/24 vous fait avancer d'une heure. Les trois fonctions
d'horloge ne diffèrent que par la partie du nombre qu'elles remplissent :
Nowremplit les deux parties — le jour entier et l'heure décimale.Datene remplit que l'entier — aujourd'hui, la fraction forcée à0(minuit).Timene remplit que la fraction — l'heure du jour, la partie entière à0.
Voilà tout le modèle. Le reste de ce guide, c'est ce qui arrive quand vous oubliez quelle partie est remplie.
Now vs Date vs Time : trois lectures d'une même horloge
Prenez celle qui correspond à la question que vous posez réellement :
Now— un horodatage complet, date et heure. À utiliser pour enregistrer quand quelque chose s'est produit (ws.Range("A1") = Now).Date— la date du jour à minuit. À utiliser pour la logique quel jour — cette facture est-elle en retard, est-on le week-end — là où l'heure n'est que du bruit.Time— l'heure du jour, sans date. À utiliser pour horodater une heure ou mesurer un instant au sein d'une journée.
Range("A1") = Now ' 2026-08-26 14:30:07 - un evenement journalise
Range("A2") = Date ' 2026-08-26 - une colonne d'echeance
Range("A3") = Time ' 14:30:07 - une heure de debut de poste
Now = Date + Time est vrai à la seconde près, car c'est littéralement ainsi que le nombre est construit :
Date fournit l'entier, Time fournit la fraction.
Pourquoi If stamp = Date ne correspond jamais à une valeur Now
C'est le bug vedette, et il découle directement du Double. Vous stockez un horodatage avec Now, puis
vous testez plus tard s'il s'est produit aujourd'hui :
saved = Now ' 46261.6042 (porte une fraction d'heure)
' ...plus tard...
If saved = Date Then MsgBox "today" ' Date vaut 46261.0000 - JAMAIS egal
Date est un nombre entier ; saved porte une fraction. 46261,6042 = 46261,0 vaut False, donc la
branche ne se déclenche jamais en silence — pas d'erreur, juste une logique qui ne fait discrètement rien.
Le correctif, c'est de comparer ce qui est comparable en retirant l'heure avant le test :
If Int(saved) = Date Then MsgBox "today" ' Int supprime la fraction
If DateValue(saved) = Date Then MsgBox "today" ' DateValue fait pareil, explicitement
Int(d) tronque la fraction et laisse la date pure. DateValue fait la même chose
mais se lit comme « la partie date de cette valeur », ce qui est plus clair pour la personne suivante. La
règle à retenir : ne comparez jamais une valeur issue de Now avec = sans normaliser les deux côtés à
la même précision. Le bug de date « ça marchait pourtant aux tests » est toujours une fraction parasite.
Date et Time sont aussi des instructions qui règlent l'horloge
Voici le piège qui surprend tout le monde une fois : Date et Time ne sont pas seulement des fonctions
qui lisent l'horloge — ce sont aussi des instructions qui l'écrivent. Avec une affectation à
gauche, elles modifient l'horloge système de l'ordinateur :
x = Date ' FONCTION - lit aujourd'hui dans x
Date = #2030-01-01# ' INSTRUCTION - regle la date de TOUT L'ORDINATEUR sur 2030
Time = #08:00:00# ' INSTRUCTION - regle l'heure systeme
Même mot, effet opposé, décidé entièrement par sa position à gauche ou non d'un =. Régler l'horloge
système affecte toutes les applications de la machine, exige des droits administrateur, et n'est
presque jamais ce qu'une macro de tableur devrait faire — un Date = quelque chose égaré est une coquille
véritablement dangereuse. Lisez l'horloge, ne la réglez jamais : gardez Date et Time à droite de
vos affectations.
Now donne l'heure locale, pas UTC
Now lit l'horloge locale de la machine — sa valeur dépend du fuseau horaire de l'utilisateur et du
réglage d'heure d'été. Dans un classeur partagé entre plusieurs régions, deux personnes qui cliquent sur le
même bouton horodatent deux heures différentes, et aucune n'est UTC. VBA n'a aucune fonction UTC
intégrée ; obtenir l'heure universelle passe par un appel à l'API Windows (GetSystemTime) ou un
utilitaire maison :
' Now = heure locale de l'horloge murale - parfait pour une machine,
' ambigu des que le fichier franchit un fuseau horaire.
Range("Log") = Now
Pour le classeur d'un seul utilisateur, c'est exactement ce qu'il faut, et c'est simple. Pour un journal que plusieurs régions vont lire, stockez soit l'heure UTC (via l'API), soit le fuseau horaire à côté de l'horodatage — sinon une entrée « 10:00 » ne veut rien dire sans savoir de quel 10:00 il s'agit.
Afficher un horodatage sans casser le nombre
Pour afficher une date à votre convenance, utilisez Format — mais souvenez-vous
qu'il renvoie du texte, pas une date : c'est donc réservé à l'affichage :
MsgBox Format(Now, "yyyy-mm-dd hh:nn:ss") ' une String pour un message
cell.Value = Now ' stocke le vrai Double...
cell.NumberFormat = "yyyy-mm-dd" ' ...et formate la CELLULE, pas la valeur
Écrire cell.Value = Format(Now, ...) met dans la cellule une chaîne qui ressemble à une date, et
alors SOMME, le tri et les filtres de date se cassent tous parce que la cellule est du texte. La bonne
habitude : stockez la vraie valeur Now et pilotez son apparence avec NumberFormat. Pour aller dans
l'autre sens — transformer du texte saisi par l'utilisateur en date — utilisez
CDate ou DateSerial.
Le verdict honnête : sachez quelle partie du nombre vous tenez
Now, Date et Time sont triviaux à appeler et faciles à mal employer, parce que le mauvais usage ne
lève jamais d'erreur — il compare juste discrètement les mauvais nombres. Quatre règles couvrent toute la
surface :
- Voyez le
Double→ l'entier est le jour, la fraction est l'heure.Nowa les deux ;Daten'a que l'entier ;Timen'a que la fraction. - Normalisez avant de comparer →
Int(stamp) = Date, jamaisstamp = Date. Le bug d'égalité est toujours une fraction résiduelle. - Lisez, ne réglez jamais → gardez
Date/Timeà droite du=. À gauche, elles réinitialisent l'horloge système. - Stockez la valeur, formatez la cellule → conservez le vrai
Now; servez-vous deNumberFormatouFormatpour l'apparence, sinonSOMMEet le tri se cassent.
Maîtrisez le modèle mental du Double et les deux gros morceaux — faire des calculs sur les
dates et en extraire les parties — cessent eux aussi d'être
mystérieux.
Comment ExcelMaster aide
Les bugs de date qui coûtent vraiment du temps sont les silencieux : un test = Date qui ne se déclenche
jamais, une cellule qui se trie mal parce qu'une macro y a stocké Format(Now, …) sous forme de texte, un
journal partagé dont les heures signifient des choses différentes selon le lecteur. Chacun vient d'avoir
perdu de vue quelle partie du nombre on tenait.
ExcelMaster écrit la logique d'horodatage
qui compare juste et stocke juste. Décrivez la tâche — « journalise chaque exécution avec une date et une
heure », ou « signale les lignes datées d'avant aujourd'hui » — et il produit le bon appel (Now ou
Date), normalise la comparaison avec Int/DateValue, et garde la valeur stockée comme une vraie date,
le formatage restant sur la cellule. Vous décrivez l'instant à capturer ; il écrit le code qui le capture
sans le piège de la fraction parasite.
Questions fréquentes
Quelle est la différence entre Now et Date en VBA ?
Now renvoie la date et l'heure courantes ; Date renvoie la date du jour à minuit (sans partie
horaire). Sous le capot, une date VBA est un Double où l'entier est le jour et la fraction est l'heure —
Now remplit les deux, Date ne remplit que l'entier. De ce fait, Now et Date ne sont presque jamais
égaux, même le même jour : utilisez donc Date (ou Int(Now)) chaque fois que l'heure du jour ne doit pas
compter.
Pourquoi ma comparaison de dates avec = ne marche-t-elle jamais en VBA ?
Parce qu'un côté porte une fraction d'heure et l'autre non. Une valeur issue de Now ressemble à
46261,6042, tandis que Date vaut 46261,0 : Now = Date est donc False. Retirez l'heure avant de
comparer : If Int(stamp) = Date Then … ou If DateValue(stamp) = Date Then …. Ne comparez deux dates
avec = que lorsque les deux ont été normalisées à la même précision.
Comment obtenir uniquement l'heure courante en VBA ?
Utilisez la fonction Time : t = Time renvoie l'heure du jour sans date (la partie entière du nombre est
nulle). Si vous avez un horodatage complet issu de Now et ne voulez que sa partie horaire, soustrayez la
partie date : t = Now - Int(Now), ce qui laisse la fraction. Pour l'afficher sous forme de texte, utilisez
Format(Time, "hh:nn:ss").
Now renvoie-t-il l'heure UTC en VBA ?
Non. Now renvoie l'heure locale de l'horloge de la machine, fuseau horaire et heure d'été compris.
VBA n'a pas de fonction UTC intégrée ; pour l'heure universelle, il faut un appel à l'API Windows comme
GetSystemTime. Dans un classeur partagé entre plusieurs régions, stockez l'UTC ou notez le fuseau horaire
à côté de l'horodatage, sinon une heure journalisée est ambiguë.
VBA peut-il changer la date et l'heure système ?
Oui, et c'est pour cela que c'est dangereux. Date et Time sont aussi des instructions :
Date = #2030-01-01# règle la date système de l'ordinateur et Time = #08:00:00# en règle l'horloge, ce
qui affecte toutes les applications et exige généralement des droits administrateur. Gardez Date et Time
à droite d'une affectation pour ne jamais faire que lire l'horloge, jamais la régler.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 26/08/2026.
Guides connexes : VBA DateAdd & DateDiff · VBA Weekday & DatePart · VBA Format · VBA CStr, CDate & Val · VBA Timer
