TIMESERIAL is
easy to remember, more human readable and spot on
Between [Enter CallDate] And ([Enter CallDate] + TimeSerial(23, 59,
59))
And how is this simpler than
= [Enter CallDate] AND < DateAdd("d", 1, [Enter CallDate])
?
Mine isn't simpler; in fact, yours may be a better suited to Access/
Jet's floating point nature of DATETIME values (with caveat, see
below). But it's a case of 'apples and oranges' because yours is
fundamentally different approach.
You, John, are using closed-open representation of a period, where the
end date (instant) does not fall within the period itself. On the
other hand, Jerry is using the closed-closed representation, where the
end date is the last time granule (one second accuracy for Access/Jet)
within the period.
Now I like Jerry-closed-closed representation myself because I prefer
to state one 'fact' using one predicate:
target_date BETWEEN start_date AND end_date
The above is simple and easily understood by the person who inherits
my code. To do the same using the John-closed-open representation
requires two predicates:
start_date <= target_date
AND target_date < end_date
I find the <= then < to be less intuitive than BETWEEN (you can't use
BETWEEN with closed-open representation and expect correct results).
Also I find the fact that the end date is not within the period to non-
intuitive e.g. contrast the respective representations for the current
year (square bracket = closed, parenthesis = open):
[#2007-01-01 00:00:00#, #2008-01-01 23:59:59#]
[#2007-01-01 00:00:00#, #2008-01-01 00:00:00#)
I find that using a date in 2008 to represent the period 2007 to be,
well, odd.
I do have problems with the Jerry-closed-closed representation as
well. Primarily, it assumes DATETIME values of being of the same
granularity, in this case one second. My response to this is to always
use temporal functionality and put validation rules on every DATETIME
column to ensure they are, which works but DATETIME values of sub-
second granularity (as Jerry will get with by adding an approximate
DECIMAL to a DATETIME) will be rounded, fine by me but may cause some
people problems e.g.
SELECT
#2007-01-01 00:00:00# AS start_date_closed,
#2007-12-31 23:59:59# AS end_date_closed,
#2008-01-31 00:00:00# AS end_date_open,
#2007-12-31 00:00:00# + 0.99999 as target_date,
target_date BETWEEN start_date_closed AND end_date_closed
AS result_jerry_closed_closed,
(end_date_closed <= target_date AND target_date < end_date_open)
AS result_john_closed_open
The 'Jerry' result is FALSE and the 'John' result is TRUE. Getting a
TRUE result is arguably better.
Now for that caveat I mentioned. The most common representation I see
in the Access groups is a closed-closed representation BUT with one
day granularity and without taking any steps to ensure DATETIME values
are rounded to one day granularity e.g. the current year period:
[#2007-01-01 00:00:00#, #2007-12-31 00:00:00#]
Such users are going to have problems much more frequently because
they are omitting the 86398 DATETIME values between #2007-12-31
00:00:01# and #2007-12-31 23:59:59# inclusive from the timeline. Hence
we get almost daily posts about 'missing dates' and the ubiquitous
'dates are floating point' replies.
But what about the parameter value? Let's use yours as an example:
= [Enter CallDate] AND < DateAdd("d", 1, [Enter CallDate])
Let's assume this supposed to get all values that falls on the same
calendar day as the parameter value (because it's usually the case
here).
The above assumes that the parameter value will be a DATETIME value
with midnight as it's time value but let's say the person entered
39310.99999 (the only reason I can think of for a parameter name
'Enter CallDate', with an annoying space in it, is that a user will
see it); even with strongly typed parameter values (not always the
case in the groups, even for DATETIME values) the start- and end dates
aren't going to come out as intended e.g.
SELECT
CDATE(39310.99999) AS [Enter CallDate],
[Enter CallDate] AS start_date_closed,
DateAdd("d", 1, [Enter CallDate]) AS end_date_open
retuns
[#2007-08-16 23:59:59#, #2007-08-17 23:59:59#]
i.e. mostly the next day!
My approach for temporal data is to use strongly typed DATETIME values
and ensure their values are of known granularity, and that granularity
is usually (always?) one second for me. This is why -- finally gets to
the point -- I posted my recommendation that when using the closed-
closed representation the parameter value should get 'rounded' e.g.
SELECT
39310.99999 AS [Enter CallDate],
DATEADD('D', DATEDIFF('D', #1990-01-01 00:00:00#, [Enter CallDate]),
#1990-01-01 00:00:00#) AS start_date_closed,
DATEADD('D', DATEDIFF('D', #1990-01-01 00:00:00#, [Enter CallDate]),
#1990-01-01 23:59:59#) AS end_date_closed
returns
[#2007-08-16 00:00:00#, #2007-08-16 23:59:59#]
Jamie.
--