Determine whether a date log handle contains the most recent calendar market date
IsDateLogHandleUpToDate checks whether the most recent calendar market date (today, or the nearest prior non-holiday, non-weekend day) is already present in the date log core of the given DATE_LOG_HANDLE.
Use it to decide whether a date log needs to be extended (for example with LoadDateLogHandle and the DATE_LOG_AUTO_UPDATE_FLAG flag) before it is considered current for downstream operations such as an ODBC fetch or update. The function only reports staleness; it never modifies the log.
BOOL _Check_return_ IsDateLogHandleUpToDate(
_In_ DATE_LOG_HANDLE hDateLogHandle
);
Standard C calling convention with SAL annotations for parameter validation and return value inspection. _Check_return_ means the result must be inspected. datelog.h does not list this function in its declarations; the prototype above is the one documented for this function.
[In] DATE_LOG_HANDLE
Handle whose date log core is to be checked against the most recent calendar market date.
InitializeDateLogHandle or DuplicateDateLogHandle.FALSE is returned.FALSE is returned.CloseDateLogHandle.| Value | Condition |
|---|---|
TRUE | The most recent calendar market date is present in the handle’s core. |
FALSE | The handle failed validation or locking, the most recent calendar market date could not be computed, or that date is not found in the core (the log is stale and needs updating). |
The function cannot distinguish a stale log from a failure; both yield FALSE. If you need the reason, validate the handle first with IsValidDateLogHandle and check that the log has a holidays handle with GetDateLogHolidayHandle. The library error codes that relate to these conditions are ERR_INVALID_DATELOG_HANDLE, ERR_DATELOG_NO_HOLIDAYS and ERR_INVALID_HOLIDAY_HANDLE (see date_error.h).
The temporary date item representing “most recent calendar market date” is always freed via FreeDateItem before returning, and the handle is always unlocked in the __finally block.
The handle is validated and locked for the duration of the check. A locking failure is reported as FALSE, which looks the same as a stale log; treat FALSE as “do not assume the log is current”. Use DuplicateDateLogHandle so that each thread has its own handle onto the shared context.
CloseDateLogHandle. Handles that share a context are reference counted.LoadDateLogHandle if FALSE is returned. DATE_LOG_AUTO_UPDATE_FLAG requires a valid file context and a DATE_LOG_HANDLE (not a range or holidays handle).DateLogHandleHasChanged reports whether the in-memory log differs from what was loaded, which callers use to decide whether the underlying file must be rewritten.GetDateCollectionLength and GetDateCollectionMaximumLength report the number of items and the capacity of the log.GetMostRecentCallendarMarketDate (declared in datelog.h) returns the most recent market date as a date item and can be used to display the date that this function compares against.LoadDateLogHandleIsValidDateLogHandleDateLogHandleHasChangedGetDateLogHolidayHandleGetDateCollectionLengthInitializeDateLogHandleFreeDateItemCloseDateLogHandleThe sample builds a log that ends on 2025-03-31, validates it, reports its length, and then asks whether it contains the most recent calendar market date. Because the log ends in the past, the check reports that it is stale; the sample prints the market date being compared and exits with code 2 to signal that an update is needed. Every handle and date item is released on every path.
#include <Windows.h>
#include <stdio.h>
#include "datelog.h"
static BOOL MakeFileTime(WORD wYear, WORD wMonth, WORD wDay, PFILETIME pFt)
{
SYSTEMTIME st = { 0 };
st.wYear = wYear;
st.wMonth = wMonth;
st.wDay = wDay;
return SystemTimeToFileTime(&st, pFt);
}
/* Creates a holidays handle and loads it with the range [first, last]. */
static HRESULT BuildHolidays(PFILETIME pFirst, PFILETIME pLast, HOLIDAYS_HANDLE *phHolidays)
{
HRESULT hr = S_OK;
HOLIDAYS_HANDLE hHolidays = NULL;
DATE_ITEM_HANDLE hFirst = NULL;
DATE_ITEM_HANDLE hLast = NULL;
*phHolidays = NULL;
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hHolidays, HandleIsForHolidays);
if (FAILED(hr)) goto cleanup;
hr = InitializeDateItem(hHolidays, pFirst, NULL, &hFirst);
if (FAILED(hr)) goto cleanup;
hr = InitializeDateItem(hHolidays, pLast, NULL, &hLast);
if (FAILED(hr)) goto cleanup;
hr = LoadDateLogHandle(NULL, hFirst, hLast, hHolidays, NULL, 0);
if (FAILED(hr)) goto cleanup;
*phHolidays = hHolidays;
hHolidays = NULL;
cleanup:
FreeDateItem(hLast);
FreeDateItem(hFirst);
if (hHolidays != NULL) {
(void)CloseDateLogHandle(hHolidays);
}
return hr;
}
/* Creates a date log or range handle of the given type and generates [first, last] into it. */
static HRESULT BuildCollection(HOLIDAYS_HANDLE hHolidays, DateHandleType type,
PFILETIME pFirst, PFILETIME pLast, DATE_LOG_HANDLE *phCollection)
{
HRESULT hr = S_OK;
DATE_LOG_HANDLE hCollection = NULL;
DATE_ITEM_HANDLE hFirst = NULL;
DATE_ITEM_HANDLE hLast = NULL;
*phCollection = NULL;
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, hHolidays, &hCollection, type);
if (FAILED(hr)) goto cleanup;
hr = InitializeDateItem(hHolidays, pFirst, NULL, &hFirst);
if (FAILED(hr)) goto cleanup;
hr = InitializeDateItem(hHolidays, pLast, NULL, &hLast);
if (FAILED(hr)) goto cleanup;
hr = LoadDateLogHandle(NULL, hFirst, hLast, hCollection, NULL, 0);
if (FAILED(hr)) goto cleanup;
*phCollection = hCollection;
hCollection = NULL;
cleanup:
FreeDateItem(hLast);
FreeDateItem(hFirst);
if (hCollection != NULL) {
(void)CloseDateLogHandle(hCollection);
}
return hr;
}
int main(void)
{
int exitCode = 1;
HRESULT hr = S_OK;
FILETIME ftFirst = { 0 };
FILETIME ftLast = { 0 };
HOLIDAYS_HANDLE hHolidays = NULL;
DATE_LOG_HANDLE hDateLog = NULL;
DATE_ITEM_HANDLE hMostRecent = NULL;
DWORD dwLength = 0;
if (!MakeFileTime(2025, 1, 2, &ftFirst) || !MakeFileTime(2025, 3, 31, &ftLast)) {
printf("Invalid calendar date.\n");
return 1;
}
hr = BuildHolidays(&ftFirst, &ftLast, &hHolidays);
if (FAILED(hr)) {
printf("BuildHolidays failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
hr = BuildCollection(hHolidays, HandleIsForDatelog, &ftFirst, &ftLast, &hDateLog);
if (FAILED(hr)) {
printf("BuildCollection failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
/* Separate invalid handles and missing holidays from a stale log. */
if (!IsValidDateLogHandle(hDateLog)) {
printf("The date log handle is not valid.\n");
goto cleanup;
}
dwLength = GetDateCollectionLength(hDateLog);
if (dwLength > DATE_LOG_MAX) {
printf("GetDateCollectionLength reported a failure.\n");
goto cleanup;
}
printf("The date log holds %lu date items.\n", (unsigned long)dwLength);
if (IsDateLogHandleUpToDate(hDateLog)) {
printf("The date log already contains the most recent market date.\n");
exitCode = 0;
} else {
SYSTEMTIME st = { 0 };
FILETIME ftRecent = { 0 };
/* Show which date the check is comparing against. */
hr = GetMostRecentCallendarMarketDate(hDateLog, &hMostRecent);
if (SUCCEEDED(hr) &&
GetDateItemFiletime(hMostRecent, &ftRecent) &&
FileTimeToSystemTime(&ftRecent, &st)) {
printf("The date log is stale; the most recent market date is %04u-%02u-%02u.\n",
st.wYear, st.wMonth, st.wDay);
} else {
printf("The date log is stale or could not be checked.\n");
}
/* Extend the log with LoadDateLogHandle() (for example with DATE_LOG_AUTO_UPDATE_FLAG
for a file-backed log) before using it for ODBC operations. */
exitCode = 2;
}
cleanup:
FreeDateItem(hMostRecent);
if (hDateLog != NULL) {
(void)CloseDateLogHandle(hDateLog);
}
if (hHolidays != NULL) {
(void)CloseDateLogHandle(hHolidays);
}
return exitCode;
}