Calculate the number of market days between two date items
GetDateItemHandleGap is the public wrapper around the internal GetMarketDaysGap(),
resolving the holidays handle from a DATE_LOG_HANDLE's context automatically and returning the
number of market days between two date items.
Allows callers who only have a date log/range handle (not a raw holidays handle) to compute market-day gaps without manually extracting the holidays handle. Market days exclude weekends and the holidays defined by the associated holidays collection.
hDateLogHandle automaticallyDateGapSpecDATE_LOG_SENTINEL
LONG _Check_return_ _On_failure_(return > DATE_LOG_MAX) GetDateItemHandleGap(
_In_ DATE_LOG_HANDLE hDateLogHandle,
_In_ DATE_ITEM_HANDLE hStartDate,
_In_ DATE_ITEM_HANDLE hEndDate,
_In_ DateGapSpec DateGapType
);
[In] DATE_LOG_HANDLE
Handle whose associated holidays handle supplies the market calendar.
DATE_LOG_SENTINEL.InitializeDateLogHandle() requires one for date log and range handles).[In] DATE_ITEM_HANDLE
The starting date item.
DATE_LOG_SENTINEL).InitializeDateItem() or an item from the collection (FindDateItemHandle()).[In] DATE_ITEM_HANDLE
The ending date item.
DATE_LOG_SENTINEL).hStartDate. A start date later than the end date yields a negative result.[In] DateGapSpec
Controls how the boundaries are counted.
InclusiveDateGap: both start and end dates are included in the gap.ExclusiveDateGap: only dates between the start and the end are included.DATE_LOG_SENTINEL.The function returns a LONG, not an HRESULT. Gaps may legitimately be negative, so detect failure with the _On_failure_ contract (result > DATE_LOG_MAX), not with FAILED/SUCCEEDED.
| Return value | Meaning |
|---|---|
0 .. DATE_LOG_MAX (or negative) | Number of market days between the two dates; negative if hStartDate is after hEndDate. |
DATE_LOG_SENTINEL | Returned on invalid parameters, invalid DateGapType, lock failure, or if the computed gap would exceed DATE_LOG_MAX. |
Internally the function delegates entirely to the internal GetMarketDaysGap(), using pDateLog->pContext->hHolidays as the holidays handle. The date log handle is locked while the gap is computed and unlocked before return.
DuplicateDateLogHandle()) to avoid contending on one handle's mutex.ERR_DATE_NO_COVERED (see date_error.h) but this function itself only returns DATE_LOG_SENTINEL.DATE_LOG_MAX (370,120) is not representable and fails.InitializeDateItem() to build the start/end items, CompareDateItem() for ordering, IsDateItemHoliday() to test single dates.signed int GetDateItemGap(hDateLogHandle, hStartDate, hEndDate, DateGapType) (same four parameters, different name and no
_On_failure_ annotation) and describes InclusiveDateGap as "both start and end dates included" and
ExclusiveDateGap as "only dates between start and end included". The parameter descriptions above follow that
enumeration reference. Also note that because the result is a signed LONG, the failure test
> DATE_LOG_MAX only works if DATE_LOG_SENTINEL is a positive value above DATE_LOG_MAX.
#include <Windows.h>
#include <stdio.h>
#include "datelog.h"
static BOOL MakeFiletime(WORD wYear, WORD wMonth, WORD wDay, PFILETIME pFiletime)
{
SYSTEMTIME st = { 0 };
st.wYear = wYear;
st.wMonth = wMonth;
st.wDay = wDay;
return SystemTimeToFileTime(&st, pFiletime);
}
int main(void)
{
HOLIDAYS_HANDLE hHolidays = NULL;
DATE_LOG_HANDLE hDateLog = NULL;
DATE_ITEM_HANDLE hStart = NULL;
DATE_ITEM_HANDLE hEnd = NULL;
FILETIME ftStart = { 0 };
FILETIME ftEnd = { 0 };
HRESULT hr = E_FAIL;
int exitCode = 1;
LONG lInclusive = 0;
LONG lExclusive = 0;
LONG lReverse = 0;
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hHolidays, HandleIsForHolidays);
if (FAILED(hr)) {
printf("InitializeDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, hHolidays, &hDateLog, HandleIsForDatelog);
if (FAILED(hr)) {
printf("InitializeDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
if (!MakeFiletime(2026, 1, 5, &ftStart) || !MakeFiletime(2026, 3, 31, &ftEnd)) {
printf("SystemTimeToFileTime failed: %lu\n", GetLastError());
goto cleanup;
}
/* Standalone date items; the caller owns them and frees them with FreeDateItem. */
hr = InitializeDateItem(hHolidays, &ftStart, NULL, &hStart);
if (FAILED(hr)) {
printf("InitializeDateItem [start] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
hr = InitializeDateItem(hHolidays, &ftEnd, NULL, &hEnd);
if (FAILED(hr)) {
printf("InitializeDateItem [end] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
/* The holidays collection is populated first, then the date log over the same range. */
hr = LoadDateLogHandle(NULL, hStart, hEnd, hHolidays, NULL, 0);
if (FAILED(hr)) {
printf("LoadDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
hr = LoadDateLogHandle(NULL, hStart, hEnd, hDateLog, NULL, 0);
if (FAILED(hr)) {
printf("LoadDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
/* Failure is reported in-band with DATE_LOG_SENTINEL, which is greater than DATE_LOG_MAX. */
lInclusive = GetDateItemHandleGap(hDateLog, hStart, hEnd, InclusiveDateGap);
if (lInclusive > DATE_LOG_MAX) {
printf("GetDateItemHandleGap [inclusive] failed.\n");
goto cleanup;
}
lExclusive = GetDateItemHandleGap(hDateLog, hStart, hEnd, ExclusiveDateGap);
if (lExclusive > DATE_LOG_MAX) {
printf("GetDateItemHandleGap [exclusive] failed.\n");
goto cleanup;
}
/* Swapping start and end yields a negative gap. */
lReverse = GetDateItemHandleGap(hDateLog, hEnd, hStart, InclusiveDateGap);
if (lReverse > DATE_LOG_MAX) {
printf("GetDateItemHandleGap [reversed] failed.\n");
goto cleanup;
}
printf("Market days 2026-01-05 .. 2026-03-31\n");
printf(" inclusive: %ld\n exclusive: %ld\n reversed : %ld\n", lInclusive, lExclusive, lReverse);
exitCode = 0;
cleanup:
FreeDateItem(hEnd);
FreeDateItem(hStart);
if (hDateLog != NULL) {
hr = CloseDateLogHandle(hDateLog);
if (FAILED(hr)) {
printf("CloseDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
}
}
if (hHolidays != NULL) {
hr = CloseDateLogHandle(hHolidays);
if (FAILED(hr)) {
printf("CloseDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
}
}
return exitCode;
}