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

VBA Now, Date & Time in Excel — Read the Clock, and Why Date Is Also a Statement

|

VBA Now, Date & Time in Excel — Read the Clock, and Why Date Is Also a Statement

TL;DRNow returns the date and time, Date returns today at midnight, and Time returns the time-of-day only. Underneath they are all one number: a VBA date is a Double where the integer part is the day and the fraction is the time. That is why If stamp = Date almost never matches a value that came from NowNow carries a fraction, Date does not. Drop the time with Int(Now) or DateValue(Now) before you compare.

Sub ClockDemo()
    Debug.Print Now          ' 2026-08-26 14:30:07  — date + time
    Debug.Print Date         ' 2026-08-26           — today at midnight
    Debug.Print Time         ' 14:30:07             — time only
    Debug.Print Int(Now)     ' 2026-08-26           — Now with the time dropped = Date
End Sub

A VBA date is not a special type you cannot see into — it is a plain Double wearing a mask. The whole part counts days since 30 December 1899; the fractional part is the time of day (0.5 = noon). Now, Date, and Time are just three ways of reading the same clock into that number. Once you can see the Double, every date-comparison bug in your macros turns out to be the same story: a stray fraction where you did not expect one.

What you'll learn

  • The mental model — a date is a Double: integer = day, fraction = time
  • Why Now, Date, and Time return different numbers from the same clock
  • Why If stamp = Date silently never matches a Now value — and how to fix it
  • That Date and Time are also statements that reset the system clock
  • Why Now is local time, not UTC, in a shared workbook
  • How to format a stamp for display without breaking the number underneath

The mental model: a date is a Double

The single idea that makes all of this click: a VBA Date value is a number. Assign Now to a Double and VBA shows you the machinery:

Dim d As Double
d = Now                       ' e.g. 46261.6042
' 46261     -> days since 1899-12-30  -> the date
' 0.6042    -> fraction of a day      -> ~14:30 the time

The integer part is the serial day number; the fractional part is the time as a fraction of 24 hours. 0.25 is 6 a.m., 0.5 is noon, 0.75 is 6 p.m. Everything else follows from this. Adding 1 moves you one day; adding 1/24 moves you one hour. The three clock functions differ only in which part of the number they fill in:

  • Now fills in both parts — integer day and fractional time.
  • Date fills in only the integer — today, with the fraction forced to 0 (midnight).
  • Time fills in only the fraction — the time of day, with the integer part 0.

That is the whole model. The rest of this guide is what happens when you forget which part is filled in.

Now vs Date vs Time: three reads of one clock

Reach for the one that matches the question you are actually asking:

  • Now — a full timestamp, date and time. Use it to record when something happened (ws.Range("A1") = Now).
  • Date — today's calendar date at midnight. Use it for which day logic — is this invoice overdue, is today a weekend — where the time of day is noise.
  • Time — the time of day with no date. Use it to stamp a time or measure a wall-clock moment within a day.
Range("A1") = Now      ' 2026-08-26 14:30:07  — logged an event
Range("A2") = Date     ' 2026-08-26           — a due-date column
Range("A3") = Time     ' 14:30:07             — a shift start time

Now = Date + Time is true to the second, because that is literally how the number is built: Date supplies the integer, Time supplies the fraction.

Why If stamp = Date never matches a Now value

This is the headline bug, and it follows directly from the Double. You store a timestamp with Now, then later test whether it happened today:

saved = Now                       ' 46261.6042  (has a time fraction)
' ...later...
If saved = Date Then MsgBox "today"   ' Date is 46261.0000 — NEVER equal

Date is a whole number; saved carries a fraction. 46261.6042 = 46261.0 is False, so the branch silently never fires — no error, just logic that quietly does nothing. The fix is to compare like with like by dropping the time before the test:

If Int(saved) = Date Then MsgBox "today"        ' Int drops the fraction
If DateValue(saved) = Date Then MsgBox "today"  ' DateValue does the same, by intent

Int(d) truncates the fraction, leaving the pure date. DateValue does the same but reads as "the date part of this value," which is clearer to the next person. The rule to carry away: never compare a Now-derived value with = unless both sides are normalized to the same precision. The "it worked in testing" date bug is always a stray fraction.

Date and Time are also statements that set the clock

Here is the trap that surprises everyone once: Date and Time are not only functions that read the clock — they are also statements that write it. With an assignment on the left, they change the computer's system clock:

x = Date              ' FUNCTION — reads today into x
Date = #2030-01-01#   ' STATEMENT — sets the WHOLE COMPUTER's date to 2030
Time = #08:00:00#     ' STATEMENT — sets the system time

Same word, opposite effect, decided entirely by whether it sits on the left of an =. Setting the system clock affects every application on the machine, needs administrator rights, and is almost never what a spreadsheet macro should do — a stray Date = something is a genuinely dangerous typo. Read the clock, never set it: keep Date and Time on the right-hand side of your assignments.

Now is local time, not UTC

Now reads the machine's local clock — its value depends on the user's time zone and daylight-saving setting. In a workbook shared across regions, two people clicking the same button stamp two different times, and neither is UTC. VBA has no built-in UTC function; getting universal time needs a Windows API call (GetSystemTime) or a helper:

' Now = local wall-clock time — fine for one machine,
' ambiguous the moment the file crosses a time zone.
Range("Log") = Now

For a single user's workbook this is exactly right and simple. For a log that several regions will read, either store UTC (via the API) or record the time zone alongside the stamp — otherwise a "10:00" entry means nothing without knowing whose 10:00 it was.

Displaying a stamp without breaking the number

To show a date the way you want, use Format — but remember it returns text, not a date, so it is for display only:

MsgBox Format(Now, "yyyy-mm-dd hh:nn:ss")   ' a String for a message
cell.Value = Now                            ' store the real Double...
cell.NumberFormat = "yyyy-mm-dd"            ' ...and format the CELL, not the value

Writing cell.Value = Format(Now, ...) puts a string that looks like a date into the cell, and then SUM, sorting, and date filters all break because the cell is text. The correct habit: store the real Now value and control its appearance with NumberFormat. To go the other way — turn user-typed text into a date — use CDate or DateSerial.

The honest verdict: know which part of the number you hold

Now, Date, and Time are trivial to call and easy to misuse, because the misuse never raises an error — it just quietly compares the wrong numbers. Four rules cover the whole surface:

  • See the Double → integer is the day, fraction is the time. Now has both; Date has only the integer; Time has only the fraction.
  • Normalize before you compareInt(stamp) = Date, never stamp = Date. The equality bug is always a leftover fraction.
  • Read, never set → keep Date/Time on the right of =. On the left they reset the system clock.
  • Store the value, format the cell → keep the real Now; use NumberFormat or Format for how it looks, or SUM and sorting break.

Get the Double mental model right and the two heavy lifts — doing math on dates and pulling parts back out — stop being mysterious too.

How ExcelMaster helps

The date bugs that cost real time are the silent ones: a = Date check that never fires, a cell that sorts wrong because a macro stored Format(Now, …) as text, a shared log whose times mean different things to different readers. Each one comes from losing track of which part of the number you are holding.

ExcelMaster writes the timestamp logic that compares correctly and stores correctly. Describe the job — "log each run with a date and time," or "flag rows dated before today" — and it produces the right call (Now vs Date), normalizes the comparison with Int/DateValue, and keeps the stored value a real date with the formatting on the cell. You describe the moment you want to capture; it writes the code that captures it without the stray-fraction trap.

Frequently asked questions

What is the difference between Now and Date in VBA?

Now returns the current date and time; Date returns today's date at midnight (no time part). Under the hood a VBA date is a Double where the integer is the day and the fraction is the time — Now fills in both, Date fills in only the integer. Because of that, Now and Date are almost never equal even on the same day, so use Date (or Int(Now)) whenever the time of day should not matter.

Why does my date comparison with = never work in VBA?

Because one side carries a time fraction and the other does not. A value from Now looks like 46261.6042, while Date is 46261.0, so Now = Date is False. Drop the time before comparing: If Int(stamp) = Date Then … or If DateValue(stamp) = Date Then …. Only compare two dates with = when both have been normalized to the same precision.

How do I get just the current time in VBA?

Use the Time function: t = Time returns the time of day with no date (the integer part of the number is zero). If you have a full timestamp from Now and want only its time portion, subtract the date part: t = Now - Int(Now), which leaves the fraction. To display it as text use Format(Time, "hh:nn:ss").

Does Now return UTC time in VBA?

No. Now returns the machine's local wall-clock time, including its time-zone and daylight-saving offset. VBA has no built-in UTC function; for universal time you need a Windows API call such as GetSystemTime. In a workbook shared across regions, store UTC or record the time zone next to the stamp, or a logged time is ambiguous.

Can VBA change the system date and time?

Yes, and that is why it is dangerous. Date and Time are also statements: Date = #2030-01-01# sets the computer's system date and Time = #08:00:00# sets its clock, affecting every application and usually requiring administrator rights. Keep Date and Time on the right-hand side of an assignment so you only ever read the clock, never set it.

Tested in

Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-08-26.

Related guides: VBA DateAdd & DateDiff · VBA Weekday & DatePart · VBA Format · VBA CStr, CDate & Val · VBA Timer