Matching a time value in a cell to read the correct value of Now...

chazrab

Well-known Member
Joined
Oct 21, 2006
Messages
882
Office Version
  1. 365
Platform
  1. Windows
This code
Code:
' Option Explicit
Dim MyRunTimer As Date
col headers A = Date  B = Time C = Message
Sub MyMacro()
MyRunTimer = Now + TimeValue("00:00:10")
Dim i As Variant, t As Date, s As String
If Range("D1") <> "" Then
   Exit Sub
Else
    For i = 2 To [A65536].End(xlUp).Row
         If Cells(i, 1).Value = DateValue(Now) Then  'if col A is today's date - works great
             If Cells(i, 2).Value = TimeSerial(Now) Then
             MsgBox "Both date and time values of current date and time match"
         Else
             MsgBox "code wrong"
         End If
    Next
   Application.OnTime MyRunTimer, "MyMacro"
End If
End Sub
This macro just repeats itself and checks col A , col B and col C every 10 seconds
to see if a new value of Date, Time and Message has been entered.

When an entered value in col A and B matches Now, a Msgbox displays
saying so.("Date and TIme value of Now found". Col A is formatted as Date mm/dd/yyyy, col B is formatted as Time(1:30 PM) and C as string.

I can't figure out how to tell Excel to read the correct Time value in col B as
the current time and display the message. Excel reads the correct Date
for Now with this code perfectly every time
Code:
Cells(i, 1).Value = DateValue(Now)

Can someone please help with the correct code for telling Excel the value in
col B is the correct time. It's either with the code line for reading the time correctly 'or the formatting or both.

Thanks for anyone's help.
cr
 

Excel Facts

How can you turn a range sideways?
Copy the range. Select a blank cell. Right-click, Paste Special, then choose Transpose.
Could it be that time has simply moved on (even if only by a millisecond) by the time the code is testing the value with NOW() and therefore never matches EXACTLY

What is the value in column B and how does it get there ?
 
Last edited:
Upvote 0
Could it be that time has simply moved on (even if only by a millisecond) by the time the code is testing the value with NOW() and therefore never matches EXACTLY

What is the value in column B and how does it get there ?

Hi Yongle - good question. The value in col B is entered from DTPicker2 on a userform formatted as dpCustom hh:mm:ss tt.

As for the time millisecond question, then how would you be able to compare a cell value of time in a column range that has a future time, with Now() through a repeating macro, and if a match is found, display a MsgBox on the screen?.



Every time you type in Now() in a cell it reads like this: 12:50:24 PM, which I just typed into a cell, formatted as time. This tells me that Excel reads time values to the second, not millisecond, unless you know something I don't about the Windows system clock and its relationship to Excel's Now() function. Please enlighten me. Thx for all your help. As you can see, all I'm wanting to do is simply enter a correctly formatted time value for a future time and when Now() is reached, displays a message. But it has to match the time to Now() first and exactly.
cr
 
Upvote 0
Every time you type in Now() in a cell it reads like this: 12:50:24 PM, which I just typed into a cell, formatted as time. This tells me that Excel reads time values to the second, not millisecond, unless you know something I don't about the Windows system clock and its relationship to Excel's Now() function. Please enlighten me.

NOW() is specified to 10 decimal places but displayed to the nearest second by default

Try putting =NOW() into a cell and then formatting that cell as a number to 15 decimal places. You will get something like this:
43673.821011342600000
43673 is 27 July 2019
0.8210113426 is the time element


Iif all you care about is that a particular time has elapsed why not test if TIME in cell is GREATER than NOW()
or LESS than NOW() if that is the correct test for what you want

I will test a few ideas and reply to your question tomorrow
 
Last edited:
Upvote 0
NOW() is specified to 10 decimal places but displayed to the nearest second by default

Try putting =NOW() into a cell and then formatting that cell as a number to 15 decimal places. You will get something like this:
43673.821011342600000
43673 is 27 July 2019
0.8210113426 is the time element


Iif all you care about is that a particular time has elapsed why not test if TIME in cell is GREATER than NOW()
or LESS than NOW() if that is the correct test for what you want

I will test a few ideas and reply to your question tomorrow

Thanks - I'm looking forward to hearing back from you on this.
cr
 
Upvote 0
1. Perhaps one of these two methods will give you what you want

2. "Date and time" tests combined into a single line (or use separate line to test date and time separately as per your original code)
- there are 2 separate tests which yield the same result - one numerically achieved and the other by building text string
- modify tests to suit the result required by you (code below ignores seconds)

3.
The worksheet below illustrates by formula what the code returns.

Excel 2016 (Windows) 32 bit
A
B
C
D
E
F
G
H
1
DateTime
28/07/2019 13:00​
Numerical
Test
Formula in D2 copied downTEXT
Equiv
Formula in G2 copied down
2
27/07/2019​
13:00:00​
=IF(AND(NOW()-(A2+B2)>=0,NOW()-(A2+B2)<(1/24/60)),"Match","") =IF(TEXT(NOW(),"dd/mm/yy HH:MM")=TEXT((A2+B2),"dd/mm/yy HH:MM"),"Match","")
3
27/07/2019​
08:16:00​
4
27/07/2019​
08:20:00​
5
27/07/2019​
08:17:00​
6
27/07/2019​
08:16:00​
7
27/07/2019​
08:17:00​
8
27/07/2019​
09:01:00​
9
27/07/2019​
13:00:00
10
27/07/2019​
13:00:00
11
28/07/2019​
13:00:00
MatchMatch
12
28/07/2019​
13:00:00
MatchMatch
13
28/07/2019​
08:35:00​
14
28/07/2019​
08:20:00​
15
28/07/2019​
08:17:00​
16
28/07/2019​
09:01:00​
17
28/07/2019​
13:00:00
MatchMatch
18
28/07/2019​
13:00:00
MatchMatch
19
29/07/2019​
13:00:00
20
29/07/2019​
13:00:00
21
29/07/2019​
12:40:00​
22
29/07/2019​
12:40:00​
23
29/07/2019​
12:40:00​
24
29/07/2019​
14:19:00​
25
29/07/2019​
15:19:00​
Sheet: Sheet1

Notes:
Formula in cell C1 is = NOW()
Sample data includes 3 dates and various times
8 rows contain the correct date, 8 rows contain correct time, 4 rows contain both
4. With data as per above, VBA returned this in Message Box

28/07/2019 13:00:22
numerically
row 11 28/07/2019 13:00:00
row 12 28/07/2019 13:00:00
row 17 28/07/2019 13:00:00
row 18 28/07/2019 13:00:00

by text
row 11 28/07/2019 13:00:00
row 12 28/07/2019 13:00:00
row 17 28/07/2019 13:00:00
row 18 28/07/2019 13:00:00

5. Sample code containing the tests
Code:
Sub testTime()
    Application.Calculate
    Dim i As Long, D_T As Date, N As Date, msg1 As String, msg2 As String
    Const M = 1 / 60 / 24
    N = Now
    
    For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
        D_T = Cells(i, 1) + Cells(i, 2)
[COLOR=#006400][I]
'numerical test[/I][/COLOR]
        If N - D_T > 0 And N - D_T < M Then
            msg1 = msg1 & vbCr & "row " & i & " " & D_T
        End If
[COLOR=#006400][I]'text test[/I][/COLOR]
        If Format(N, "dd/mm/yy HH:MM") = Format(D_T, "dd/mm/yy HH:MM") Then
            msg2 = msg2 & vbCr & "row " & i & " " & D_T
        End If
    Next
[I][COLOR=#006400]'result[/COLOR][/I]
    If Not msg1 & msg2 = "" Then msg1 = "numerically" & msg1 & vbCr & vbCr & "by text" & msg2 Else msg1 = "No match"
    MsgBox msg1, , N
    
End Sub
 
Upvote 0
The value in col B is entered from DTPicker2 on a userform formatted as dpCustom hh:mm:ss tt. [....] Every time you type in Now() in a cell it reads like this: 12:50:24 PM, which I just typed into a cell, formatted as time. This tells me that Excel reads time values to the second, not millisecond, unless you know something I don't about the Windows system clock and its relationship to Excel's Now() function. Please enlighten me.
NOW() is specified to 10 decimal places but displayed to the nearest second by default

It might help to clear up some misunderstandings.

No, time is not "specified to 10 decimal places". It is just that Excel formats and displays only up to 15 significant digits.

There is an important difference between VBA Now() and Excel NOW().

VBA Now() returns time rounded down to the second.

Excel NOW() returns time rounded down to the 1/100 second (multiples of 10 milliseconds).

But when Excel and VBA format time as h:m:s or h:m, fraction seconds are rounded. For example, the time 12:34:56.789 formatted as h:mm:ss is formatted as 12:34:57 .

The Windows system clock is updated (a "tick") every 15.625 milliseconds, usually. Applications can alter that frequency, and some do. The effect is system-wide. So it is prudent to terminate all extraneous applications.

VBA Timer returns time of day in seconds and fractional seconds. Since it is type Single, not Double, time is accurate to 1/128 second or better, depending on the time of day. (And depending on an adjustment factor that the system clock appears to add, presumably to account for time drift.)

These facts can be demonstrated with the following VBA function:

Rich (BB code):
Function tod() As Variant
Dim xlnow As Double, vbatimer As Double, vbanow As Double
Dim res(1 To 3, 1 To 2) As Double
xlnow = [now()]
vbatimer = Timer    ' type Single converted to Double
vbanow = Now
res(1, 1) = vbatimer / 86400
res(1, 2) = vbatimer
res(2, 1) = xlnow
res(2, 2) = (xlnow - Int(xlnow)) * 86400
res(3, 1) = vbanow
res(3, 2) = (vbanow - Int(vbanow)) * 86400
tod = res
End Function

Select B2:C4 and array-entered (press ctrl+shift+Enter instead of just Enter) the formula =tod() . Format B2 as [hh]:mm:ss.000 . Format B3:B4 as m/dd/yyyy hh:mm:ss.000 . Format C2:C4 as Number with 15 decimal places.

Function tod() is purposely not "volatile". Press ctrl+alt+f9 to recalculate A1:B3.

In one example, the results are:

ABCD
1Date + TODTOD secondsTOD seconds (exact)
2VBA Timer 09:14:45.35533285.35546875000000033285.35546875
3Excel NOW7/28/2019 09:14:45.35033285.35000004330000033285.3500000433,487002737820148468017578125
4VBA Now7/28/2019 09:14:45.00033285.00000005580000033285.0000000558,429746888577938079833984375

<tbody>
</tbody>


Column D shows the exact TOD in seconds, using my own formatter. I use period for the decimal point and comma to demarcate the first 15 signficant digits.

The infinitesimal differences in columns C and D are due to anomalies of the internal 64-bit binary floating-point respresentation. In a nutshell: time of day is stored as a fraction of a day; most decimal fractions cannot be represented exactly; and the binary approximation of a particular decimal fraction varies depending on the magnitude of the number.


Rich (BB code):
' Option Explicit
Dim MyRunTimer As Date
col headers A = Date  B = Time C = Message
Sub MyMacro()
MyRunTimer = Now + TimeValue("00:00:10")
Dim i As Variant, t As Date, s As String
If Range("D1") <> "" Then
   Exit Sub
Else
    For i = 2 To [A65536].End(xlUp).Row
         If Cells(i, 1).Value = DateValue(Now) Then  'if col A is today's date - works great
             If Cells(i, 2).Value = TimeSerial(Now) Then
             MsgBox "Both date and time values of current date and time match"
         Else
             MsgBox "code wrong"
         End If
    Next
   Application.OnTime MyRunTimer, "MyMacro"
End If
End Sub

The posted code contains several fatal errors, highlighted in red: missing single-quote for the comment "col headers..."; TimeSerial(Now) should be TimeValue(Now); and missing EndIf, presumably before Next.

It is unclear to me how time values are entered into Cells(i,2). You say that you use DTPicker2, which returns time in the form hh:mm:ss tt [sic] (presumably representing tt/100 seconds). I am not familiar with DTPicker2. But that is not a valid numeric Excel time form (missing period between "ss" and "tt"). I don't know if that is just another posting typo.

Ostensibly, the comparison Cells(i,2) = TimeValue(Now) might be changed to Format(Cells(i,2),"h:m:s") = Format(Now,"h:m:s") .

But as noted above, formatting Cells(i,2) might result in a false difference if fractional seconds are rounded up.

I suspect the following will work:

Dim t As Double
t = Time
If Int(86400 * Cells(i,2)) <> Int(86400 * (t - Int(t))) Then

It seems to be reliable, based on a brief test. But I worry about possible binary arithmetic anomalies.

-----

Aside.... There is no reason to use DateValue(Now) and TimeValue(Now). Simply use Date and Time, respectively.

However, if you might execute the code near midnight, it would be more reliable to capture date and time of day once, either before or within the loop, depending on your intentions (which are not clear to me). For example:

Dim n as Double, d as Double, t as Double
n = Now
d = Int(n)
t = n - Int(n)

d is the date. t is the time of day.

-----

PS....

Instead of nested "If" statements, I suggest effectively the following (correcting the time comparison):

If Cells(i, 1).Value = DateValue(Now) And Cells(i, 2).Value = TimeSerial(Now) Then

That would eliminated the syntax error due to a missing End If.

(But perhaps the broken code that you posted was an attempt to isolate the failure.)
 
Last edited:
Upvote 0
I suspect the following will work:

Dim t As Double
t = Time
If Int(86400 * Cells(i,2)) <> Int(86400 * (t - Int(t))) Then

It seems to be reliable, based on a brief test. But I worry about possible binary arithmetic anomalies.

Aarrgghh! I spoke too soon. I stumbled across an example where the comparison fails the above test, but in fact, they should match. The failure is due to binary anomalies.

Back to the drawing board! Sorry for the misdirection.

(Frankly, I don't think this should be so difficult. I suspect I'm just over-thinking it. Klunk!)

-----

PS.... How about:

Left(Worksheetfunction.Text(Cells(i,2),"hh:mm:ss.000"),8) = Format(Time,"hh:mm:ss")
 
Last edited:
Upvote 0
Instead of nested "If" statements, I suggest effectively the following (correcting the time comparison):
If Cells(i, 1).Value = DateValue(Now) And Cells(i, 2).Value = TimeSerial(Now) Then
How about:
Left(Worksheetfunction.Text(Cells(i,2),"hh:mm:ss.000"),8) = Format(Time,"hh:mm:ss")

And if you're intent is to compare date and time together, like the AND expression, how about:

Left(Worksheetfunction.Text(Cells(i,1)+Cells(i,2),"mm/dd/yyyy hh:mm:ss.000"),19) = Format(Now,"mm/dd/yyyy hh:mm:ss")

Again, the reason for using the "ss.000" format is to avoid rounding fractional seconds when formatting as "h:m:s" and to avoid binary arithmetic anomalies when calculating Int(86400*Cells(i,2)).
 
Upvote 0
Hi Joeu - thanks for helping. I don't want to sound like a simpleton, but after trying to understand everything you wrote, I'm confused. A brief review of my issue:
1) I have a userform with DTPicker1 to enter any date as 07/28/2019 in col A and DTPicker2 to enter time as 1:30 PM in col B, and Textbox1 to enter any reminder or message in col C.

Values are recorded in Sheet1 starting in row 2 and on down until the data ends.

So what I have built is a sheet with future events. Like
07/30/2019(col A) 10:00 AM(col B) Check balance in account (col C)
07/30/2019(col A) 11:00 AM(col B) Go to store (col C)
07/31/2019(col A) 1:00 PM (col B) Work out (col C)

My idea of how this should work correctly every time:
A For loop checks each row starting in row 2 and compares two things with Now(I'm confused "now" as to whether VBA Now or Excel NOW) 1: the date in col A to today's Date (you say =Date), and the time in col B of the same row on that date.
Desired result:
if the date in col A is today's date(Date), and the time in col B is Time(the current time - represented by NOW, be it VBA or Excel NOW, ), the code just displays the message 1 - for that Date and 2 - at that time.

Judging from above comments, code and examples, the above two replies indicate an advanced knowledge greater than I of what needs to be done to have this work correctly every time - with the simplest possible code.

Regarding the use of a DTPicker for Date and Time entry, I'm not tied down to using it. If comboboxes would be better, I'm OK with that.

This is just an Excel based custom Reminder. There are many out there. So my thinking, is if it can be done with whatever tools they are developed in( C, C++, etc), why can't one be built in and for Excel to operate within the confines of an Excel business or personal app(like a Budget spreadsheet). I'm not into using Task Scheduler or any other external Reminder app. Too easy.

This has been a very tiring challenge for me to this point because I'm not as knowledgeable in Excel. My view, is that there has to be a way to develop this within Excel using Application.onTime.
checking every hour, not every second all day long. Going checking every second all day seems like it would use way to much memory if that 's what it does.

From what's above, a lot of time and thought has been spent on this and I appreciate it.
Thanks again many x's for everyone's help.
cr
 
Upvote 0

Forum statistics

Threads
1,214,634
Messages
6,120,659
Members
448,975
Latest member
sweeberry

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top